github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/jsonformat/computed/renderers/map.go (about) 1 package renderers 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 8 "github.com/hashicorp/terraform/internal/command/jsonformat/computed" 9 10 "github.com/hashicorp/terraform/internal/plans" 11 ) 12 13 var _ computed.DiffRenderer = (*mapRenderer)(nil) 14 15 func Map(elements map[string]computed.Diff) computed.DiffRenderer { 16 return &mapRenderer{ 17 elements: elements, 18 alignKeys: true, 19 } 20 } 21 22 func NestedMap(elements map[string]computed.Diff) computed.DiffRenderer { 23 return &mapRenderer{ 24 elements: elements, 25 overrideNullSuffix: true, 26 overrideForcesReplacement: true, 27 } 28 } 29 30 type mapRenderer struct { 31 NoWarningsRenderer 32 33 elements map[string]computed.Diff 34 35 overrideNullSuffix bool 36 overrideForcesReplacement bool 37 alignKeys bool 38 } 39 40 func (renderer mapRenderer) RenderHuman(diff computed.Diff, indent int, opts computed.RenderHumanOpts) string { 41 forcesReplacementSelf := diff.Replace && !renderer.overrideForcesReplacement 42 forcesReplacementChildren := diff.Replace && renderer.overrideForcesReplacement 43 44 if len(renderer.elements) == 0 { 45 return fmt.Sprintf("{}%s%s", nullSuffix(diff.Action, opts), forcesReplacement(forcesReplacementSelf, opts)) 46 } 47 48 // Sort the map elements by key, so we have a deterministic ordering in 49 // the output. 50 var keys []string 51 52 // We need to make sure the keys are capable of rendering properly. 53 escapedKeys := make(map[string]string) 54 55 maximumKeyLen := 0 56 for key := range renderer.elements { 57 keys = append(keys, key) 58 59 escapedKey := hclEscapeString(key) 60 escapedKeys[key] = escapedKey 61 if maximumKeyLen < len(escapedKey) { 62 maximumKeyLen = len(escapedKey) 63 } 64 } 65 sort.Strings(keys) 66 67 unchangedElements := 0 68 69 elementOpts := opts.Clone() 70 elementOpts.OverrideNullSuffix = diff.Action == plans.Delete || renderer.overrideNullSuffix 71 elementOpts.OverrideForcesReplacement = forcesReplacementChildren 72 73 var buf bytes.Buffer 74 buf.WriteString(fmt.Sprintf("{%s\n", forcesReplacement(forcesReplacementSelf, opts))) 75 for _, key := range keys { 76 element := renderer.elements[key] 77 78 if element.Action == plans.NoOp && !opts.ShowUnchangedChildren { 79 // Don't render NoOp operations when we are compact display. 80 unchangedElements++ 81 continue 82 } 83 84 for _, warning := range element.WarningsHuman(indent+1, opts) { 85 buf.WriteString(fmt.Sprintf("%s%s\n", formatIndent(indent+1), warning)) 86 } 87 // Only show commas between elements for objects. 88 comma := "" 89 if _, ok := element.Renderer.(*objectRenderer); ok { 90 comma = "," 91 } 92 93 if renderer.alignKeys { 94 buf.WriteString(fmt.Sprintf("%s%s%-*s = %s%s\n", formatIndent(indent+1), writeDiffActionSymbol(element.Action, elementOpts), maximumKeyLen, escapedKeys[key], element.RenderHuman(indent+1, elementOpts), comma)) 95 } else { 96 buf.WriteString(fmt.Sprintf("%s%s%s = %s%s\n", formatIndent(indent+1), writeDiffActionSymbol(element.Action, elementOpts), escapedKeys[key], element.RenderHuman(indent+1, elementOpts), comma)) 97 } 98 99 } 100 101 if unchangedElements > 0 { 102 buf.WriteString(fmt.Sprintf("%s%s%s\n", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), unchanged("element", unchangedElements, opts))) 103 } 104 105 buf.WriteString(fmt.Sprintf("%s%s}%s", formatIndent(indent), writeDiffActionSymbol(plans.NoOp, opts), nullSuffix(diff.Action, opts))) 106 return buf.String() 107 }