From 8abca06c29ab5fd9c15b8ed7802126cea3b17c43 Mon Sep 17 00:00:00 2001 From: Liam Cervante Date: Fri, 10 Mar 2023 16:04:09 +0100 Subject: [PATCH] Fix no-op outputs causing the plan renderer to skip the 'no changes' message --- internal/command/jsonformat/plan.go | 11 +++-- internal/command/jsonformat/plan_test.go | 55 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/internal/command/jsonformat/plan.go b/internal/command/jsonformat/plan.go index dce6dded6093..5deaeca54467 100644 --- a/internal/command/jsonformat/plan.go +++ b/internal/command/jsonformat/plan.go @@ -84,7 +84,11 @@ func (plan Plan) renderHuman(renderer Renderer, mode plans.Mode, opts ...PlanRen } } - if len(changes) == 0 && len(diffs.outputs) == 0 { + // Precompute the outputs early, so we can make a decision about whether we + // display the "there are no changes messages". + outputs := renderHumanDiffOutputs(renderer, diffs.outputs) + + if len(changes) == 0 && len(outputs) == 0 { // If we didn't find any changes to report at all then this is a // "No changes" plan. How we'll present this depends on whether // the plan is "applyable" and, if so, whether it had refresh changes @@ -219,10 +223,9 @@ func (plan Plan) renderHuman(renderer Renderer, mode plans.Mode, opts ...PlanRen counts[plans.Delete]+counts[plans.DeleteThenCreate]+counts[plans.CreateThenDelete]) } - diff := renderHumanDiffOutputs(renderer, diffs.outputs) - if len(diff) > 0 { + if len(outputs) > 0 { renderer.Streams.Print("\nChanges to Outputs:\n") - renderer.Streams.Printf("%s\n", diff) + renderer.Streams.Printf("%s\n", outputs) if len(counts) == 0 { // If we have output changes but not resource changes then we diff --git a/internal/command/jsonformat/plan_test.go b/internal/command/jsonformat/plan_test.go index 770db9f2141d..cbde010cb119 100644 --- a/internal/command/jsonformat/plan_test.go +++ b/internal/command/jsonformat/plan_test.go @@ -1,7 +1,9 @@ package jsonformat import ( + "encoding/json" "fmt" + "github.com/hashicorp/terraform/internal/terminal" "testing" "github.com/hashicorp/terraform/internal/command/jsonformat/differ/attribute_path" @@ -22,6 +24,59 @@ import ( "github.com/hashicorp/terraform/internal/terraform" ) +func TestRenderHuman_EmptyPlan(t *testing.T) { + color := &colorstring.Colorize{Colors: colorstring.DefaultColors, Disable: true} + streams, done := terminal.StreamsForTesting(t) + + plan := Plan{} + + renderer := Renderer{Colorize: color, Streams: streams} + plan.renderHuman(renderer, plans.NormalMode) + + want := ` +No changes. Your infrastructure matches the configuration. + +Terraform has compared your real infrastructure against your configuration +and found no differences, so no changes are needed. +` + + got := done(t).Stdout() + if diff := cmp.Diff(want, got); len(diff) > 0 { + t.Errorf("unexpected output\ngot:\n%s\nwant:\n%s\ndiff:\n%s", got, want, diff) + } +} + +func TestRenderHuman_EmptyOutputs(t *testing.T) { + color := &colorstring.Colorize{Colors: colorstring.DefaultColors, Disable: true} + streams, done := terminal.StreamsForTesting(t) + + outputVal, _ := json.Marshal("some-text") + plan := Plan{ + OutputChanges: map[string]jsonplan.Change{ + "a_string": { + Actions: []string{"no-op"}, + Before: outputVal, + After: outputVal, + }, + }, + } + + renderer := Renderer{Colorize: color, Streams: streams} + plan.renderHuman(renderer, plans.NormalMode) + + want := ` +No changes. Your infrastructure matches the configuration. + +Terraform has compared your real infrastructure against your configuration +and found no differences, so no changes are needed. +` + + got := done(t).Stdout() + if diff := cmp.Diff(want, got); len(diff) > 0 { + t.Errorf("unexpected output\ngot:\n%s\nwant:\n%s\ndiff:\n%s", got, want, diff) + } +} + func TestResourceChange_primitiveTypes(t *testing.T) { testCases := map[string]testCase{ "creation": {