github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/jsonformat/computed/renderers/set.go (about)

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