diff --git a/command/format/state.go b/command/format/state.go index f411ef9c6..0130f5cf1 100644 --- a/command/format/state.go +++ b/command/format/state.go @@ -75,11 +75,14 @@ func State(opts *StateOpts) string { v := m.OutputValues[k] p.buf.WriteString(fmt.Sprintf("%s = ", k)) p.writeValue(v.Value, plans.NoOp, 0) - p.buf.WriteString("\n\n") + p.buf.WriteString("\n") } } - return opts.Color.Color(strings.TrimSpace(p.buf.String())) + trimmedOutput := strings.TrimSpace(p.buf.String()) + trimmedOutput += "[reset]" + + return opts.Color.Color(trimmedOutput) } @@ -99,9 +102,9 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf taintStr := "" if v.Current.Status == 'T' { - taintStr = "(tainted)" + taintStr = " (tainted)" } - p.buf.WriteString(fmt.Sprintf("# %s: %s\n", addr.Absolute(m.Addr).Instance(k), taintStr)) + p.buf.WriteString(fmt.Sprintf("# %s:%s\n", addr.Absolute(m.Addr).Instance(k), taintStr)) var schema *configschema.Block provider := m.Resources[key].ProviderConfig.ProviderConfig.StringCompact() @@ -169,7 +172,7 @@ func formatStateModule(p blockBodyDiffPrinter, m *states.Module, schemas *terraf p.buf.WriteString("}\n\n") } } - p.buf.WriteString("[reset]\n") + p.buf.WriteString("\n") } func formatNestedList(indent string, outputList []interface{}) string { @@ -231,7 +234,7 @@ func formatListOutput(indent, outputName string, outputList []interface{}) strin func formatNestedMap(indent string, outputMap map[string]interface{}) string { ks := make([]string, 0, len(outputMap)) - for k, _ := range outputMap { + for k := range outputMap { ks = append(ks, k) } sort.Strings(ks) @@ -256,7 +259,7 @@ func formatNestedMap(indent string, outputMap map[string]interface{}) string { func formatMapOutput(indent, outputName string, outputMap map[string]interface{}) string { ks := make([]string, 0, len(outputMap)) - for k, _ := range outputMap { + for k := range outputMap { ks = append(ks, k) } sort.Strings(ks) diff --git a/command/format/state_test.go b/command/format/state_test.go index b39a15c62..5bd6ea34c 100644 --- a/command/format/state_test.go +++ b/command/format/state_test.go @@ -1,6 +1,7 @@ package format import ( + "fmt" "testing" "github.com/hashicorp/terraform/addrs" @@ -18,46 +19,6 @@ var disabledColorize = &colorstring.Colorize{ } func TestState(t *testing.T) { - state := states.NewState() - - rootModule := state.RootModule() - if rootModule == nil { - t.Errorf("root module is nil; want valid object") - } - - rootModule.SetLocalValue("foo", cty.StringVal("foo value")) - rootModule.SetOutputValue("bar", cty.StringVal("bar value"), false) - rootModule.SetResourceInstanceCurrent( - addrs.Resource{ - Mode: addrs.ManagedResourceMode, - Type: "test_resource", - Name: "baz", - }.Instance(addrs.IntKey(0)), - &states.ResourceInstanceObjectSrc{ - Status: states.ObjectReady, - SchemaVersion: 1, - AttrsJSON: []byte(`{"woozles":"confuzles"}`), - }, - addrs.ProviderConfig{ - Type: "test", - }.Absolute(addrs.RootModuleInstance), - ) - rootModule.SetResourceInstanceCurrent( - addrs.Resource{ - Mode: addrs.DataResourceMode, - Type: "test_data_source", - Name: "data", - }.Instance(addrs.NoKey), - &states.ResourceInstanceObjectSrc{ - Status: states.ObjectReady, - SchemaVersion: 1, - AttrsJSON: []byte(`{"compute":"sure"}`), - }, - addrs.ProviderConfig{ - Type: "test", - }.Absolute(addrs.RootModuleInstance), - ) - tests := []struct { State *StateOpts Want string @@ -72,11 +33,11 @@ func TestState(t *testing.T) { }, { &StateOpts{ - State: state, + State: basicState(t), Color: disabledColorize, Schemas: testSchemas(), }, - TestOutput, + basicStateOutput, }, { &StateOpts{ @@ -84,18 +45,28 @@ func TestState(t *testing.T) { Color: disabledColorize, Schemas: testSchemas(), }, - nestedTestOutput, + nestedStateOutput, + }, + { + &StateOpts{ + State: stateWithMoreOutputs(t), + Color: disabledColorize, + Schemas: testSchemas(), + }, + stateWithMoreOutputsOutput, }, } - for _, tt := range tests { - got := State(tt.State) - if got != tt.Want { - t.Errorf( - "wrong result\ninput: %v\ngot: \n%s\nwant: \n%s", - tt.State.State, got, tt.Want, - ) - } + for i, tt := range tests { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + got := State(tt.State) + if got != tt.Want { + t.Errorf( + "wrong result\ninput: %v\ngot: \n%q\nwant: \n%q", + tt.State.State, got, tt.Want, + ) + } + }) } } @@ -157,12 +128,12 @@ func testSchemas() *terraform.Schemas { } } -const TestOutput = `# data.test_data_source.data: +const basicStateOutput = `# data.test_data_source.data: data "test_data_source" "data" { compute = "sure" } -# test_resource.baz[0]: +# test_resource.baz[0]: resource "test_resource" "baz" { woozles = "confuzles" } @@ -172,16 +143,109 @@ Outputs: bar = "bar value"` -const nestedTestOutput = `# test_resource.baz[0]: +const nestedStateOutput = `# test_resource.baz[0]: resource "test_resource" "baz" { woozles = "confuzles" nested { value = "42" } +}` + +const stateWithMoreOutputsOutput = `# test_resource.baz[0]: +resource "test_resource" "baz" { + woozles = "confuzles" } -` + +Outputs: + +bool_var = true +int_var = 42 +map_var = { + "first" = "foo" + "second" = "bar" +} +sensitive_var = "secret!!!" +string_var = "string value"` + +func basicState(t *testing.T) *states.State { + state := states.NewState() + + rootModule := state.RootModule() + if rootModule == nil { + t.Errorf("root module is nil; want valid object") + } + + rootModule.SetLocalValue("foo", cty.StringVal("foo value")) + rootModule.SetOutputValue("bar", cty.StringVal("bar value"), false) + rootModule.SetResourceInstanceCurrent( + addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test_resource", + Name: "baz", + }.Instance(addrs.IntKey(0)), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + SchemaVersion: 1, + AttrsJSON: []byte(`{"woozles":"confuzles"}`), + }, + addrs.ProviderConfig{ + Type: "test", + }.Absolute(addrs.RootModuleInstance), + ) + rootModule.SetResourceInstanceCurrent( + addrs.Resource{ + Mode: addrs.DataResourceMode, + Type: "test_data_source", + Name: "data", + }.Instance(addrs.NoKey), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + SchemaVersion: 1, + AttrsJSON: []byte(`{"compute":"sure"}`), + }, + addrs.ProviderConfig{ + Type: "test", + }.Absolute(addrs.RootModuleInstance), + ) + return state +} + +func stateWithMoreOutputs(t *testing.T) *states.State { + state := states.NewState() + + rootModule := state.RootModule() + if rootModule == nil { + t.Errorf("root module is nil; want valid object") + } + + rootModule.SetOutputValue("string_var", cty.StringVal("string value"), false) + rootModule.SetOutputValue("int_var", cty.NumberIntVal(42), false) + rootModule.SetOutputValue("bool_var", cty.BoolVal(true), false) + rootModule.SetOutputValue("sensitive_var", cty.StringVal("secret!!!"), true) + rootModule.SetOutputValue("map_var", cty.MapVal(map[string]cty.Value{ + "first": cty.StringVal("foo"), + "second": cty.StringVal("bar"), + }), false) + + rootModule.SetResourceInstanceCurrent( + addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test_resource", + Name: "baz", + }.Instance(addrs.IntKey(0)), + &states.ResourceInstanceObjectSrc{ + Status: states.ObjectReady, + SchemaVersion: 1, + AttrsJSON: []byte(`{"woozles":"confuzles"}`), + }, + addrs.ProviderConfig{ + Type: "test", + }.Absolute(addrs.RootModuleInstance), + ) + return state +} func nestedState(t *testing.T) *states.State { state := states.NewState() diff --git a/command/state_show_test.go b/command/state_show_test.go index 245d14eec..e1c574e9a 100644 --- a/command/state_show_test.go +++ b/command/state_show_test.go @@ -59,10 +59,10 @@ func TestStateShow(t *testing.T) { } // Test that outputs were displayed - expected := strings.TrimSpace(testStateShowOutput) + "\n\n\n" + expected := strings.TrimSpace(testStateShowOutput) + "\n" actual := ui.OutputWriter.String() if actual != expected { - t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) + t.Fatalf("Expected:\n%q\n\nTo equal:\n%q", actual, expected) } } @@ -126,10 +126,10 @@ func TestStateShow_multi(t *testing.T) { } // Test that outputs were displayed - expected := strings.TrimSpace(testStateShowOutput) + "\n\n\n" + expected := strings.TrimSpace(testStateShowOutput) + "\n" actual := ui.OutputWriter.String() if actual != expected { - t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) + t.Fatalf("Expected:\n%q\n\nTo equal:\n%q", actual, expected) } } @@ -183,7 +183,7 @@ func TestStateShow_emptyState(t *testing.T) { } const testStateShowOutput = ` -# test_instance.foo: +# test_instance.foo: resource "test_instance" "foo" { bar = "value" foo = "value"