github.com/opentofu/opentofu@v1.7.1/internal/command/jsonformat/computed/renderers/set.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package renderers 7 8 import ( 9 "bytes" 10 "fmt" 11 12 "github.com/opentofu/opentofu/internal/command/jsonformat/computed" 13 "github.com/opentofu/opentofu/internal/plans" 14 ) 15 16 var _ computed.DiffRenderer = (*setRenderer)(nil) 17 18 func Set(elements []computed.Diff) computed.DiffRenderer { 19 return &setRenderer{ 20 elements: elements, 21 } 22 } 23 24 func NestedSet(elements []computed.Diff) computed.DiffRenderer { 25 return &setRenderer{ 26 elements: elements, 27 overrideForcesReplacement: true, 28 } 29 } 30 31 type setRenderer struct { 32 NoWarningsRenderer 33 34 elements []computed.Diff 35 36 overrideForcesReplacement bool 37 } 38 39 func (renderer setRenderer) RenderHuman(diff computed.Diff, indent int, opts computed.RenderHumanOpts) string { 40 // Sets are a bit finicky, nested sets don't render the forces replacement 41 // suffix themselves, but push it onto their children. So if we are 42 // overriding the forces replacement setting, we set it to true for children 43 // and false for ourselves. 44 displayForcesReplacementInSelf := diff.Replace && !renderer.overrideForcesReplacement 45 displayForcesReplacementInChildren := diff.Replace && renderer.overrideForcesReplacement 46 47 if len(renderer.elements) == 0 { 48 return fmt.Sprintf("[]%s%s", nullSuffix(diff.Action, opts), forcesReplacement(displayForcesReplacementInSelf, opts)) 49 } 50 51 elementOpts := opts.Clone() 52 elementOpts.OverrideNullSuffix = true 53 elementOpts.OverrideForcesReplacement = displayForcesReplacementInChildren 54 55 unchangedElements := 0 56 57 var buf bytes.Buffer 58 buf.WriteString(fmt.Sprintf("[%s\n", forcesReplacement(displayForcesReplacementInSelf, opts))) 59 for _, element := range renderer.elements { 60 if element.Action == plans.NoOp && !opts.ShowUnchangedChildren { 61 unchangedElements++ 62 continue 63 } 64 65 for _, warning := range element.WarningsHuman(indent+1, opts) { 66 buf.WriteString(fmt.Sprintf("%s%s\n", formatIndent(indent+1), warning)) 67 } 68 buf.WriteString(fmt.Sprintf("%s%s%s,\n", formatIndent(indent+1), writeDiffActionSymbol(element.Action, elementOpts), element.RenderHuman(indent+1, elementOpts))) 69 } 70 71 if unchangedElements > 0 { 72 buf.WriteString(fmt.Sprintf("%s%s%s\n", formatIndent(indent+1), writeDiffActionSymbol(plans.NoOp, opts), unchanged("element", unchangedElements, opts))) 73 } 74 75 buf.WriteString(fmt.Sprintf("%s%s]%s", formatIndent(indent), writeDiffActionSymbol(plans.NoOp, opts), nullSuffix(diff.Action, opts))) 76 return buf.String() 77 }