From 7db2825646e457bd45bd865d7a90de90d398c2fd Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 6 Nov 2019 15:59:54 -0800 Subject: [PATCH] command/format: multi-line rendering for unchanged strings We have a special treatment for multi-line strings that are being updated in-place where we show them across multiple lines in the plan output, but we didn't use that same treatment for rendering multi-line strings in isolation such as when they are being added for the first time. Here we detect when we're rendering a multi-line string in a no-change situation and render it using the diff renderer instead, using the same value for old and new and thus producing a multi-line result without any diff markers at all. This improves consistency between the change and no-change cases, and makes multi-line strings (such as YAML in block mode) readable in all cases. --- command/format/diff.go | 15 +++++++++++++++ command/format/diff_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/command/format/diff.go b/command/format/diff.go index f28b4f2b1..92d33294d 100644 --- a/command/format/diff.go +++ b/command/format/diff.go @@ -520,6 +520,21 @@ func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, in } } } + + if strings.Contains(val.AsString(), "\n") { + // It's a multi-line string, so we want to use the multi-line + // rendering so it'll be readable. Rather than re-implement + // that here, we'll just re-use the multi-line string diff + // printer with no changes, which ends up producing the + // result we want here. + // The path argument is nil because we don't track path + // information into strings and we know that a string can't + // have any indices or attributes that might need to be marked + // as (requires replacement), which is what that argument is for. + p.writeValueDiff(val, val, indent, nil) + break + } + fmt.Fprintf(p.buf, "%q", val.AsString()) case cty.Bool: if val.True() { diff --git a/command/format/diff_test.go b/command/format/diff_test.go index afbed3c8d..cd1ae9f10 100644 --- a/command/format/diff_test.go +++ b/command/format/diff_test.go @@ -207,6 +207,37 @@ new line + new line EOT } +`, + }, + "addition of multi-line string field": { + Action: plans.Update, + Mode: addrs.ManagedResourceMode, + Before: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("i-02ae66f368e8518a9"), + "more_lines": cty.NullVal(cty.String), + }), + After: cty.ObjectVal(map[string]cty.Value{ + "id": cty.UnknownVal(cty.String), + "more_lines": cty.StringVal(`original +new line +`), + }), + Schema: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "id": {Type: cty.String, Optional: true, Computed: true}, + "more_lines": {Type: cty.String, Optional: true}, + }, + }, + RequiredReplace: cty.NewPathSet(), + Tainted: false, + ExpectedOutput: ` # test_instance.example will be updated in-place + ~ resource "test_instance" "example" { + ~ id = "i-02ae66f368e8518a9" -> (known after apply) + + more_lines = <<~EOT + original + new line + EOT + } `, }, "force-new update of multi-line string field": {