mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-07-28 21:38:25 +00:00
feat: Add an output option to filter output for custom run steps (#3518)
* feat: Add an `output` option to filter output for custom run steps
This commit is contained in:
@@ -142,7 +142,11 @@ workflows:
|
||||
myworkflow:
|
||||
plan:
|
||||
steps:
|
||||
- run: terraform init -input=false
|
||||
# If you want to hide command output from Atlantis's PR comment, use
|
||||
# the output option on the run step's expanded form.
|
||||
- run:
|
||||
command: terraform init -input=false
|
||||
output: hide
|
||||
|
||||
# If you're using workspaces you need to select the workspace using the
|
||||
# $WORKSPACE environment variable.
|
||||
@@ -264,7 +268,9 @@ workflows:
|
||||
# Reduce Terraform suggestion output
|
||||
name: TF_IN_AUTOMATION
|
||||
value: 'true'
|
||||
- run: terragrunt plan -input=false -out=$PLANFILE
|
||||
- run:
|
||||
command: terragrunt plan -input=false -out=$PLANFILE
|
||||
output: strip_refreshing
|
||||
- run: terragrunt show -json $PLANFILE > $SHOWFILE
|
||||
apply:
|
||||
steps:
|
||||
@@ -297,7 +303,9 @@ workflows:
|
||||
# Reduce Terraform suggestion output
|
||||
name: TF_IN_AUTOMATION
|
||||
value: 'true'
|
||||
- run: terragrunt plan -out $PLANFILE
|
||||
- run:
|
||||
command: terragrunt plan -input=false -out=$PLANFILE
|
||||
output: strip_refreshing
|
||||
apply:
|
||||
steps:
|
||||
- env:
|
||||
@@ -451,14 +459,28 @@ A map from string to `extra_args` for a built-in command with extra arguments.
|
||||
| init/plan/apply/import/state_rm | map[`extra_args` -> array[string]] | none | no | Use a built-in command and append `extra_args`. Only `init`, `plan`, `apply`, `import` and `state_rm` are supported as keys and only `extra_args` is supported as a value |
|
||||
|
||||
#### Custom `run` Command
|
||||
Or a custom command
|
||||
A custom command can be written in 2 ways
|
||||
|
||||
Compact:
|
||||
```yaml
|
||||
- run: custom-command
|
||||
- run: custom-command arg1 arg2
|
||||
```
|
||||
| Key | Type | Default | Required | Description |
|
||||
|-----|--------|---------|----------|----------------------|
|
||||
| run | string | none | no | Run a custom command |
|
||||
|
||||
Full
|
||||
```yaml
|
||||
- run:
|
||||
command: custom-command arg1 arg2
|
||||
output: show
|
||||
```
|
||||
| Key | Type | Default | Required | Description |
|
||||
|-----|--------------------------------------------------------------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| run | map[string -> string] | none | no | Run a custom command |
|
||||
| run.command | string | none | yes | Shell command to run |
|
||||
| run.output | string | "show" | no | How to post-process the output of this command when posted in the PR comment. The options are<br/>* `show` - preserve the full output<br/>* `hide` - hide output from comment (still visible in the real-time streaming output)<br/> * `strip_refreshing` - hide all output up until and including the last line containing "Refreshing...". This matches the behavior of the built-in `plan` command |
|
||||
|
||||
::: tip Notes
|
||||
* `run` steps in the main `workflow` are executed with the following environment variables:
|
||||
note: these variables are not available to `pre` or `post` workflows
|
||||
@@ -513,9 +535,12 @@ as the environment variable value.
|
||||
name: ENV_NAME_2
|
||||
command: 'echo "dynamic-value-$(date)"'
|
||||
```
|
||||
| Key | Type | Default | Required | Description |
|
||||
|-----------------|------------------------------------|---------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| env | map[`name` -> string, `value` -> string, `command` -> string] | none | no | Set environment variables for subsequent steps |
|
||||
| Key | Type | Default | Required | Description |
|
||||
|-----------------|-----------------------|---------|----------|-----------------------------------------------------------------------------------------------------------------|
|
||||
| env | map[string -> string] | none | no | Set environment variables for subsequent steps |
|
||||
| env.name | string | none | yes | Name of the environment variable |
|
||||
| env.value | string | none | no | Set the value of the environment variable to a hard-coded string. Cannot be set at the same time as `command` |
|
||||
| env.command | string | none | no | Set the value of the environment variable to the output of a command. Cannot be set at the same time as `value` |
|
||||
|
||||
::: tip Notes
|
||||
* `env` `command`'s can use any of the built-in environment variables available
|
||||
|
||||
@@ -72,6 +72,9 @@ workflows:
|
||||
plan:
|
||||
steps:
|
||||
- run: my-custom-command arg1 arg2
|
||||
- run:
|
||||
command: my-custom-command arg1 arg2
|
||||
output: hide
|
||||
- init
|
||||
- plan:
|
||||
extra_args: ["-lock", "false"]
|
||||
|
||||
@@ -16,6 +16,7 @@ const (
|
||||
NameArgKey = "name"
|
||||
CommandArgKey = "command"
|
||||
ValueArgKey = "value"
|
||||
OutputArgKey = "output"
|
||||
RunStepName = "run"
|
||||
PlanStepName = "plan"
|
||||
ShowStepName = "show"
|
||||
@@ -34,15 +35,18 @@ const (
|
||||
// - plan
|
||||
// - policy_check
|
||||
//
|
||||
// 2. A map for an env step with name and command or value
|
||||
// 2. A map for an env step with name and command or value, or a run step with a command and output config
|
||||
// - env:
|
||||
// name: test
|
||||
// command: echo 312
|
||||
// value: value
|
||||
// name: test
|
||||
// command: echo 312
|
||||
// value: value
|
||||
// - run:
|
||||
// command: my custom command
|
||||
// output: hide
|
||||
//
|
||||
// 3. A map for a built-in command and extra_args:
|
||||
// - plan:
|
||||
// extra_args: [-var-file=staging.tfvars]
|
||||
// extra_args: [-var-file=staging.tfvars]
|
||||
//
|
||||
// 4. A map for a custom run command:
|
||||
// - run: my custom command
|
||||
@@ -53,8 +57,8 @@ type Step struct {
|
||||
// Key will be set in case #1 and #3 above to the key. In case #2, there
|
||||
// could be multiple keys (since the element is a map) so we don't set Key.
|
||||
Key *string
|
||||
// Env will be set in case #2 above.
|
||||
Env map[string]map[string]string
|
||||
// EnvOrRun will be set in case #2 above.
|
||||
EnvOrRun map[string]map[string]string
|
||||
// Map will be set in case #3 above.
|
||||
Map map[string]map[string][]string
|
||||
// StringVal will be set in case #4 above.
|
||||
@@ -142,7 +146,7 @@ func (s Step) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
envStep := func(value interface{}) error {
|
||||
envOrRunStep := func(value interface{}) error {
|
||||
elem := value.(map[string]map[string]string)
|
||||
var keys []string
|
||||
for k := range elem {
|
||||
@@ -155,10 +159,15 @@ func (s Step) Validate() error {
|
||||
return fmt.Errorf("step element can only contain a single key, found %d: %s",
|
||||
len(keys), strings.Join(keys, ","))
|
||||
}
|
||||
for stepName, args := range elem {
|
||||
if stepName != EnvStepName {
|
||||
return fmt.Errorf("%q is not a valid step type", stepName)
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return fmt.Errorf("step element must contain at least 1 key")
|
||||
}
|
||||
|
||||
stepName := keys[0]
|
||||
args := elem[keys[0]]
|
||||
|
||||
switch stepName {
|
||||
case EnvStepName:
|
||||
var argKeys []string
|
||||
for k := range args {
|
||||
argKeys = append(argKeys, k)
|
||||
@@ -183,7 +192,35 @@ func (s Step) Validate() error {
|
||||
return fmt.Errorf("env steps only support one of the %q or %q keys, found both",
|
||||
ValueArgKey, CommandArgKey)
|
||||
}
|
||||
case RunStepName:
|
||||
argsCopy := make(map[string]string)
|
||||
for k, v := range args {
|
||||
argsCopy[k] = v
|
||||
}
|
||||
args = argsCopy
|
||||
if _, ok := args[CommandArgKey]; !ok {
|
||||
return fmt.Errorf("run step must have a %q key set", CommandArgKey)
|
||||
}
|
||||
delete(args, CommandArgKey)
|
||||
if v, ok := args[OutputArgKey]; ok {
|
||||
if !(v == valid.PostProcessRunOutputShow || v == valid.PostProcessRunOutputHide || v == valid.PostProcessRunOutputStripRefreshing) {
|
||||
return fmt.Errorf("run step %q option must be one of %q, %q, or %q", OutputArgKey, valid.PostProcessRunOutputShow, valid.PostProcessRunOutputHide, valid.PostProcessRunOutputStripRefreshing)
|
||||
}
|
||||
}
|
||||
delete(args, OutputArgKey)
|
||||
if len(args) > 0 {
|
||||
var argKeys []string
|
||||
for k := range args {
|
||||
argKeys = append(argKeys, k)
|
||||
}
|
||||
// Sort so tests can be deterministic.
|
||||
sort.Strings(argKeys)
|
||||
return fmt.Errorf("run steps only support keys %q, %q and %q, found extra keys %q", RunStepName, CommandArgKey, OutputArgKey, strings.Join(argKeys, ","))
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("%q is not a valid step type", stepName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -214,8 +251,8 @@ func (s Step) Validate() error {
|
||||
if len(s.Map) > 0 {
|
||||
return validation.Validate(s.Map, validation.By(extraArgs))
|
||||
}
|
||||
if len(s.Env) > 0 {
|
||||
return validation.Validate(s.Env, validation.By(envStep))
|
||||
if len(s.EnvOrRun) > 0 {
|
||||
return validation.Validate(s.EnvOrRun, validation.By(envOrRunStep))
|
||||
}
|
||||
if len(s.StringVal) > 0 {
|
||||
return validation.Validate(s.StringVal, validation.By(runStep))
|
||||
@@ -232,16 +269,21 @@ func (s Step) ToValid() valid.Step {
|
||||
}
|
||||
|
||||
// This will trigger in case #2 (see Step docs).
|
||||
if len(s.Env) > 0 {
|
||||
if len(s.EnvOrRun) > 0 {
|
||||
// After validation we assume there's only one key and it's a valid
|
||||
// step name so we just use the first one.
|
||||
for stepName, stepArgs := range s.Env {
|
||||
return valid.Step{
|
||||
for stepName, stepArgs := range s.EnvOrRun {
|
||||
step := valid.Step{
|
||||
StepName: stepName,
|
||||
EnvVarName: stepArgs[NameArgKey],
|
||||
RunCommand: stepArgs[CommandArgKey],
|
||||
EnvVarValue: stepArgs[ValueArgKey],
|
||||
Output: valid.PostProcessRunOutputOption(stepArgs[OutputArgKey]),
|
||||
}
|
||||
if step.StepName == RunStepName && step.Output == "" {
|
||||
step.Output = valid.PostProcessRunOutputShow
|
||||
}
|
||||
return step
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +356,7 @@ func (s *Step) unmarshalGeneric(unmarshal func(interface{}) error) error {
|
||||
var envStep map[string]map[string]string
|
||||
err = unmarshal(&envStep)
|
||||
if err == nil {
|
||||
s.Env = envStep
|
||||
s.EnvOrRun = envStep
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -337,8 +379,8 @@ func (s Step) marshalGeneric() (interface{}, error) {
|
||||
return s.StringVal, nil
|
||||
} else if len(s.Map) != 0 {
|
||||
return s.Map, nil
|
||||
} else if len(s.Env) != 0 {
|
||||
return s.Env, nil
|
||||
} else if len(s.EnvOrRun) != 0 {
|
||||
return s.EnvOrRun, nil
|
||||
} else if s.Key != nil {
|
||||
return s.Key, nil
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ env:
|
||||
value: direct_value
|
||||
name: test`,
|
||||
exp: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"value": "direct_value",
|
||||
"name": "test",
|
||||
@@ -96,7 +96,7 @@ env:
|
||||
command: echo 123
|
||||
name: test`,
|
||||
exp: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"command": "echo 123",
|
||||
"name": "test",
|
||||
@@ -137,7 +137,7 @@ key: value`,
|
||||
Key: nil,
|
||||
Map: nil,
|
||||
StringVal: nil,
|
||||
Env: nil,
|
||||
EnvOrRun: nil,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -227,7 +227,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "env",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"name": "test",
|
||||
"command": "echo 123",
|
||||
@@ -283,7 +283,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "multiple keys in env",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"key1": nil,
|
||||
"key2": nil,
|
||||
},
|
||||
@@ -312,7 +312,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "invalid key in env",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"invalid": nil,
|
||||
},
|
||||
},
|
||||
@@ -353,7 +353,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "env step with no name key set",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"value": "value",
|
||||
},
|
||||
@@ -364,7 +364,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "env step with invalid key",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"abc": "",
|
||||
"invalid2": "",
|
||||
@@ -376,7 +376,7 @@ func TestStep_Validate(t *testing.T) {
|
||||
{
|
||||
description: "env step with both command and value set",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"name": "name",
|
||||
"command": "command",
|
||||
@@ -454,7 +454,7 @@ func TestStep_ToValid(t *testing.T) {
|
||||
{
|
||||
description: "env step",
|
||||
input: raw.Step{
|
||||
Env: EnvType{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"env": {
|
||||
"name": "test",
|
||||
"command": "echo 123",
|
||||
@@ -558,6 +558,22 @@ func TestStep_ToValid(t *testing.T) {
|
||||
RunCommand: "my 'run command'",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "run step with output",
|
||||
input: raw.Step{
|
||||
EnvOrRun: EnvOrRunType{
|
||||
"run": {
|
||||
"command": "my 'run command'",
|
||||
"output": "hide",
|
||||
},
|
||||
},
|
||||
},
|
||||
exp: valid.Step{
|
||||
StepName: "run",
|
||||
RunCommand: "my 'run command'",
|
||||
Output: "hide",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.description, func(t *testing.T) {
|
||||
@@ -567,4 +583,4 @@ func TestStep_ToValid(t *testing.T) {
|
||||
}
|
||||
|
||||
type MapType map[string]map[string][]string
|
||||
type EnvType map[string]map[string]string
|
||||
type EnvOrRunType map[string]map[string]string
|
||||
|
||||
@@ -150,6 +150,15 @@ type Autoplan struct {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
// PostProcessRunOutputOption is an enum of options for post-processing RunCommand output
|
||||
type PostProcessRunOutputOption string
|
||||
|
||||
const (
|
||||
PostProcessRunOutputShow = "show"
|
||||
PostProcessRunOutputHide = "hide"
|
||||
PostProcessRunOutputStripRefreshing = "strip_refreshing"
|
||||
)
|
||||
|
||||
type Stage struct {
|
||||
Steps []Step
|
||||
}
|
||||
@@ -160,6 +169,8 @@ type Step struct {
|
||||
// RunCommand is either a custom run step or the command to run
|
||||
// during an env step to populate the environment variable dynamically.
|
||||
RunCommand string
|
||||
// Output is option for post-processing a RunCommand output
|
||||
Output PostProcessRunOutputOption
|
||||
// EnvVarName is the name of the
|
||||
// environment variable that should be set by this step.
|
||||
EnvVarName string
|
||||
|
||||
@@ -3,6 +3,7 @@ package runtime
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
)
|
||||
|
||||
@@ -20,7 +21,7 @@ func (r *EnvStepRunner) Run(ctx command.ProjectContext, command string, value st
|
||||
}
|
||||
// Pass `false` for streamOutput because this isn't interesting to the user reading the build logs
|
||||
// in the web UI.
|
||||
res, err := r.RunStepRunner.Run(ctx, command, path, envs, false)
|
||||
res, err := r.RunStepRunner.Run(ctx, command, path, envs, false, valid.PostProcessRunOutputShow)
|
||||
// Trim newline from res to support running `echo env_value` which has
|
||||
// a newline. We don't recommend users run echo -n env_value to remove the
|
||||
// newline because -n doesn't work in the sh shell which is what we use
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
)
|
||||
|
||||
@@ -15,7 +16,7 @@ type MultiEnvStepRunner struct {
|
||||
// Run runs the multienv step command.
|
||||
// The command must return a json string containing the array of name-value pairs that are being added as extra environment variables
|
||||
func (r *MultiEnvStepRunner) Run(ctx command.ProjectContext, command string, path string, envs map[string]string) (string, error) {
|
||||
res, err := r.RunStepRunner.Run(ctx, command, path, envs, false)
|
||||
res, err := r.RunStepRunner.Run(ctx, command, path, envs, false, valid.PostProcessRunOutputShow)
|
||||
if err == nil {
|
||||
if len(res) > 0 {
|
||||
var sb strings.Builder
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
"github.com/runatlantis/atlantis/server/core/runtime/models"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
"github.com/runatlantis/atlantis/server/jobs"
|
||||
@@ -21,7 +22,7 @@ type RunStepRunner struct {
|
||||
ProjectCmdOutputHandler jobs.ProjectCommandOutputHandler
|
||||
}
|
||||
|
||||
func (r *RunStepRunner) Run(ctx command.ProjectContext, command string, path string, envs map[string]string, streamOutput bool) (string, error) {
|
||||
func (r *RunStepRunner) Run(ctx command.ProjectContext, command string, path string, envs map[string]string, streamOutput bool, postProcessOutput valid.PostProcessRunOutputOption) (string, error) {
|
||||
tfVersion := r.DefaultTFVersion
|
||||
if ctx.TerraformVersion != nil {
|
||||
tfVersion = ctx.TerraformVersion
|
||||
@@ -75,5 +76,15 @@ func (r *RunStepRunner) Run(ctx command.ProjectContext, command string, path str
|
||||
ctx.Log.Debug("error: %s", err)
|
||||
return "", err
|
||||
}
|
||||
return output, nil
|
||||
|
||||
switch postProcessOutput {
|
||||
case valid.PostProcessRunOutputHide:
|
||||
return "", nil
|
||||
case valid.PostProcessRunOutputStripRefreshing:
|
||||
return StripRefreshingFromPlanOutput(output, tfVersion), nil
|
||||
case valid.PostProcessRunOutputShow:
|
||||
return output, nil
|
||||
default:
|
||||
return output, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
. "github.com/petergtz/pegomock/v4"
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
"github.com/runatlantis/atlantis/server/core/runtime"
|
||||
"github.com/runatlantis/atlantis/server/core/terraform/mocks"
|
||||
"github.com/runatlantis/atlantis/server/events/command"
|
||||
@@ -144,7 +145,7 @@ func TestRunStepRunner_Run(t *testing.T) {
|
||||
ProjectName: c.ProjectName,
|
||||
EscapedCommentArgs: []string{"-target=resource1", "-target=resource2"},
|
||||
}
|
||||
out, err := r.Run(ctx, c.Command, tmpDir, map[string]string{"test": "var"}, true)
|
||||
out, err := r.Run(ctx, c.Command, tmpDir, map[string]string{"test": "var"}, true, valid.PostProcessRunOutputShow)
|
||||
if c.ExpErr != "" {
|
||||
ErrContains(t, c.ExpErr, err)
|
||||
return
|
||||
|
||||
@@ -5,6 +5,7 @@ package mocks
|
||||
|
||||
import (
|
||||
pegomock "github.com/petergtz/pegomock/v4"
|
||||
valid "github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
command "github.com/runatlantis/atlantis/server/events/command"
|
||||
"reflect"
|
||||
"time"
|
||||
@@ -25,11 +26,11 @@ func NewMockCustomStepRunner(options ...pegomock.Option) *MockCustomStepRunner {
|
||||
func (mock *MockCustomStepRunner) SetFailHandler(fh pegomock.FailHandler) { mock.fail = fh }
|
||||
func (mock *MockCustomStepRunner) FailHandler() pegomock.FailHandler { return mock.fail }
|
||||
|
||||
func (mock *MockCustomStepRunner) Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool) (string, error) {
|
||||
func (mock *MockCustomStepRunner) Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool, postProcessOutput valid.PostProcessRunOutputOption) (string, error) {
|
||||
if mock == nil {
|
||||
panic("mock must not be nil. Use myMock := NewMockCustomStepRunner().")
|
||||
}
|
||||
params := []pegomock.Param{ctx, cmd, path, envs, streamOutput}
|
||||
params := []pegomock.Param{ctx, cmd, path, envs, streamOutput, postProcessOutput}
|
||||
result := pegomock.GetGenericMockFrom(mock).Invoke("Run", params, []reflect.Type{reflect.TypeOf((*string)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()})
|
||||
var ret0 string
|
||||
var ret1 error
|
||||
@@ -81,8 +82,8 @@ type VerifierMockCustomStepRunner struct {
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (verifier *VerifierMockCustomStepRunner) Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool) *MockCustomStepRunner_Run_OngoingVerification {
|
||||
params := []pegomock.Param{ctx, cmd, path, envs, streamOutput}
|
||||
func (verifier *VerifierMockCustomStepRunner) Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool, postProcessOutput valid.PostProcessRunOutputOption) *MockCustomStepRunner_Run_OngoingVerification {
|
||||
params := []pegomock.Param{ctx, cmd, path, envs, streamOutput, postProcessOutput}
|
||||
methodInvocations := pegomock.GetGenericMockFrom(verifier.mock).Verify(verifier.inOrderContext, verifier.invocationCountMatcher, "Run", params, verifier.timeout)
|
||||
return &MockCustomStepRunner_Run_OngoingVerification{mock: verifier.mock, methodInvocations: methodInvocations}
|
||||
}
|
||||
@@ -92,12 +93,12 @@ type MockCustomStepRunner_Run_OngoingVerification struct {
|
||||
methodInvocations []pegomock.MethodInvocation
|
||||
}
|
||||
|
||||
func (c *MockCustomStepRunner_Run_OngoingVerification) GetCapturedArguments() (command.ProjectContext, string, string, map[string]string, bool) {
|
||||
ctx, cmd, path, envs, streamOutput := c.GetAllCapturedArguments()
|
||||
return ctx[len(ctx)-1], cmd[len(cmd)-1], path[len(path)-1], envs[len(envs)-1], streamOutput[len(streamOutput)-1]
|
||||
func (c *MockCustomStepRunner_Run_OngoingVerification) GetCapturedArguments() (command.ProjectContext, string, string, map[string]string, bool, valid.PostProcessRunOutputOption) {
|
||||
ctx, cmd, path, envs, streamOutput, postProcessOutput := c.GetAllCapturedArguments()
|
||||
return ctx[len(ctx)-1], cmd[len(cmd)-1], path[len(path)-1], envs[len(envs)-1], streamOutput[len(streamOutput)-1], postProcessOutput[len(postProcessOutput)-1]
|
||||
}
|
||||
|
||||
func (c *MockCustomStepRunner_Run_OngoingVerification) GetAllCapturedArguments() (_param0 []command.ProjectContext, _param1 []string, _param2 []string, _param3 []map[string]string, _param4 []bool) {
|
||||
func (c *MockCustomStepRunner_Run_OngoingVerification) GetAllCapturedArguments() (_param0 []command.ProjectContext, _param1 []string, _param2 []string, _param3 []map[string]string, _param4 []bool, _param5 []valid.PostProcessRunOutputOption) {
|
||||
params := pegomock.GetGenericMockFrom(c.mock).GetInvocationParams(c.methodInvocations)
|
||||
if len(params) > 0 {
|
||||
_param0 = make([]command.ProjectContext, len(c.methodInvocations))
|
||||
@@ -120,6 +121,10 @@ func (c *MockCustomStepRunner_Run_OngoingVerification) GetAllCapturedArguments()
|
||||
for u, param := range params[4] {
|
||||
_param4[u] = param.(bool)
|
||||
}
|
||||
_param5 = make([]valid.PostProcessRunOutputOption, len(c.methodInvocations))
|
||||
for u, param := range params[5] {
|
||||
_param5[u] = param.(valid.PostProcessRunOutputOption)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -14,13 +14,12 @@
|
||||
package events
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"encoding/json"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/runatlantis/atlantis/server/core/config/valid"
|
||||
@@ -66,7 +65,7 @@ type StepRunner interface {
|
||||
// CustomStepRunner runs custom run steps.
|
||||
type CustomStepRunner interface {
|
||||
// Run cmd in path.
|
||||
Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool) (string, error)
|
||||
Run(ctx command.ProjectContext, cmd string, path string, envs map[string]string, streamOutput bool, postProcessOutput valid.PostProcessRunOutputOption) (string, error)
|
||||
}
|
||||
|
||||
//go:generate pegomock generate --package mocks -o mocks/mock_env_step_runner.go EnvStepRunner
|
||||
@@ -764,7 +763,7 @@ func (p *DefaultProjectCommandRunner) runSteps(steps []valid.Step, ctx command.P
|
||||
case "state_rm":
|
||||
out, err = p.StateRmStepRunner.Run(ctx, step.ExtraArgs, absPath, envs)
|
||||
case "run":
|
||||
out, err = p.RunStepRunner.Run(ctx, step.RunCommand, absPath, envs, true)
|
||||
out, err = p.RunStepRunner.Run(ctx, step.RunCommand, absPath, envs, true, step.Output)
|
||||
case "env":
|
||||
out, err = p.EnvStepRunner.Run(ctx, step.RunCommand, step.EnvVarValue, absPath, envs)
|
||||
envs[step.EnvVarName] = out
|
||||
|
||||
@@ -112,7 +112,7 @@ func TestDefaultProjectCommandRunner_Plan(t *testing.T) {
|
||||
When(mockInit.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("init", nil)
|
||||
When(mockPlan.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("plan", nil)
|
||||
When(mockApply.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("apply", nil)
|
||||
When(mockRun.Run(ctx, "", repoDir, expEnvs, true)).ThenReturn("run", nil)
|
||||
When(mockRun.Run(ctx, "", repoDir, expEnvs, true, "")).ThenReturn("run", nil)
|
||||
res := runner.Plan(ctx)
|
||||
|
||||
Assert(t, res.PlanSuccess != nil, "exp plan success")
|
||||
@@ -128,7 +128,7 @@ func TestDefaultProjectCommandRunner_Plan(t *testing.T) {
|
||||
case "apply":
|
||||
mockApply.VerifyWasCalledOnce().Run(ctx, nil, repoDir, expEnvs)
|
||||
case "run":
|
||||
mockRun.VerifyWasCalledOnce().Run(ctx, "", repoDir, expEnvs, true)
|
||||
mockRun.VerifyWasCalledOnce().Run(ctx, "", repoDir, expEnvs, true, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -457,7 +457,7 @@ func TestDefaultProjectCommandRunner_Apply(t *testing.T) {
|
||||
When(mockInit.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("init", nil)
|
||||
When(mockPlan.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("plan", nil)
|
||||
When(mockApply.Run(ctx, nil, repoDir, expEnvs)).ThenReturn("apply", nil)
|
||||
When(mockRun.Run(ctx, "", repoDir, expEnvs, true)).ThenReturn("run", nil)
|
||||
When(mockRun.Run(ctx, "", repoDir, expEnvs, true, "")).ThenReturn("run", nil)
|
||||
When(mockEnv.Run(ctx, "", "value", repoDir, make(map[string]string))).ThenReturn("value", nil)
|
||||
|
||||
res := runner.Apply(ctx)
|
||||
@@ -473,7 +473,7 @@ func TestDefaultProjectCommandRunner_Apply(t *testing.T) {
|
||||
case "apply":
|
||||
mockApply.VerifyWasCalledOnce().Run(ctx, nil, repoDir, expEnvs)
|
||||
case "run":
|
||||
mockRun.VerifyWasCalledOnce().Run(ctx, "", repoDir, expEnvs, true)
|
||||
mockRun.VerifyWasCalledOnce().Run(ctx, "", repoDir, expEnvs, true, "")
|
||||
case "env":
|
||||
mockEnv.VerifyWasCalledOnce().Run(ctx, "", "value", repoDir, expEnvs)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user