Skip to content

Commit

Permalink
fix(output): Remove Refreshing state... from output
Browse files Browse the repository at this point in the history
Since Terraform 0.14.0 there are no separator between refreshing plan and the plan.
  • Loading branch information
mathcantin committed Jan 15, 2021
1 parent 1137a82 commit a6e8f37
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 38 deletions.
12 changes: 4 additions & 8 deletions server/events/runtime/apply_step_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,14 @@ func (a *ApplyStepRunner) runRemoteApply(
// If the plans don't match, it returns an error with a diff of the two plans
// that can be printed to the pull request.
func (a *ApplyStepRunner) remotePlanChanged(planfileContents string, applyOut string) error {
// The plan is between the refresh separator...
planStartIdx := strings.Index(applyOut, refreshSeparator)
if planStartIdx < 0 {
return fmt.Errorf("Couldn't find refresh separator when parsing apply output:\n%q", applyOut)
}
output := stripRefreshingFromPlanOutput(applyOut)

// ...and the prompt to execute the plan.
planEndIdx := strings.Index(applyOut, "Do you want to perform these actions in workspace \"")
// The output stop to execute the plan.
planEndIdx := strings.Index(output, "Do you want to perform these actions in workspace \"")
if planEndIdx < 0 {
return fmt.Errorf("Couldn't find plan end when parsing apply output:\n%q", applyOut)
}
currPlan := strings.TrimSpace(applyOut[planStartIdx+len(refreshSeparator) : planEndIdx])
currPlan := strings.TrimSpace(output[: planEndIdx])

// Ensure we strip the remoteOpsHeader from the plan contents so the
// comparison is fair. We add this header in the plan phase so we can
Expand Down
2 changes: 0 additions & 2 deletions server/events/runtime/apply_step_runner_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ persisted to local or remote state storage.
null_resource.dir2[1]: Refreshing state... (ID: 8554368366766418126)
null_resource.dir2: Refreshing state... (ID: 8492616078576984857)
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Expand Down
1 change: 0 additions & 1 deletion server/events/runtime/apply_step_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,6 @@ persisted to local or remote state storage.
null_resource.dir2[0]: Refreshing state... (ID: 8492616078576984857)
------------------------------------------------------------------------
%s
Do you want to perform these actions in workspace "atlantis-tfe-test-dir2"?
Expand Down
34 changes: 19 additions & 15 deletions server/events/runtime/plan_step_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import (

const (
defaultWorkspace = "default"
// refreshSeparator is what separates the refresh stage from the calculated
// plan during a terraform plan.
refreshSeparator = "------------------------------------------------------------------------\n"
refreshKeyword = "Refreshing state..."
)

var (
Expand Down Expand Up @@ -89,11 +87,7 @@ func (p *PlanStepRunner) remotePlan(ctx models.ProjectCommandContext, extraArgs
// plan. To ensure that what gets applied is the plan we printed to the PR,
// during the apply phase, we diff the output we stored in the fake
// planfile with the pending apply output.
planOutput := output
sepIdx := strings.Index(planOutput, refreshSeparator)
if sepIdx > -1 {
planOutput = planOutput[sepIdx+len(refreshSeparator):]
}
planOutput := stripRefreshingFromPlanOutput(output)

// We also prepend our own remote ops header to the file so during apply we
// know this is a remote apply.
Expand Down Expand Up @@ -229,13 +223,7 @@ func (p *PlanStepRunner) flatten(slices [][]string) []string {
// We do it for +, ~ and -.
// It also removes the "Refreshing..." preamble.
func (p *PlanStepRunner) fmtPlanOutput(output string) string {
// Plan output contains a lot of "Refreshing..." lines followed by a
// separator. We want to remove everything before that separator.
sepIdx := strings.Index(output, refreshSeparator)
if sepIdx > -1 {
output = output[sepIdx+len(refreshSeparator):]
}

output = stripRefreshingFromPlanOutput(output)
output = plusDiffRegex.ReplaceAllString(output, "+")
output = tildeDiffRegex.ReplaceAllString(output, "~")
return minusDiffRegex.ReplaceAllString(output, "-")
Expand Down Expand Up @@ -299,6 +287,22 @@ func (p *PlanStepRunner) runRemotePlan(
return output, err
}

func stripRefreshingFromPlanOutput(output string) string {
// Plan output contains a lot of "Refreshing..." lines, remove it
lines := strings.Split(output, "\n")
finalIndex := 0
for i, line := range lines {
if strings.Contains(line, refreshKeyword) {
finalIndex = i
}
}

if finalIndex != 0 {
output = strings.Join(lines[finalIndex + 1:], "\n")
}
return output
}

// remoteOpsErr01114 is the error terraform plan will return if this project is
// using TFE remote operations in TF 0.11.14.
var remoteOpsErr01114 = `Error: Saving a generated plan is currently not supported!
Expand Down
14 changes: 2 additions & 12 deletions server/events/runtime/plan_step_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,14 +502,7 @@ func TestRun_UsesDiffPathForProject(t *testing.T) {

// Test that we format the plan output for better rendering.
func TestRun_PlanFmt(t *testing.T) {
rawOutput := `Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
rawOutput := `An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
~ update in-place
Expand Down Expand Up @@ -556,8 +549,7 @@ Terraform will perform the following actions:
})
actOutput, err := s.Run(models.ProjectCommandContext{Workspace: "default"}, nil, "", map[string]string(nil))
Ok(t, err)
Equals(t, `
An execution plan has been generated and is shown below.
Equals(t, `An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
~ update in-place
Expand Down Expand Up @@ -869,8 +861,6 @@ persisted to local or remote state storage.
null_resource.hi: Refreshing state... (ID: 217661332516885645)
null_resource.hi[1]: Refreshing state... (ID: 6064510335076839362)
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Expand Down

0 comments on commit a6e8f37

Please sign in to comment.