mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Structured Plan Renderer: Address comments raised in previous PRs (#32478)
* Address comments raised in previous PRs * add doc comments for public types
This commit is contained in:
parent
1332d315b6
commit
2d66eee872
@ -2014,6 +2014,8 @@ func DiffActionSymbol(action plans.Action) string {
|
||||
return " [cyan]<=[reset]"
|
||||
case plans.Update:
|
||||
return " [yellow]~[reset]"
|
||||
case plans.NoOp:
|
||||
return " "
|
||||
default:
|
||||
return " ?"
|
||||
}
|
||||
|
@ -55,10 +55,6 @@ func (renderer blockRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
buf.WriteString(fmt.Sprintf("{%s\n", change.forcesReplacement()))
|
||||
for _, importantKey := range importantAttributes {
|
||||
if attribute, ok := renderer.attributes[importantKey]; ok {
|
||||
if attribute.action == plans.NoOp {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %-*s = %s\n", change.indent(indent+1), attribute.emptySymbol(), renderer.maximumKeyLen, importantKey, attribute.Render(indent+1, opts)))
|
||||
continue
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%s%s %-*s = %s\n", change.indent(indent+1), format.DiffActionSymbol(attribute.action), renderer.maximumKeyLen, importantKey, attribute.Render(indent+1, opts)))
|
||||
}
|
||||
}
|
||||
@ -86,7 +82,7 @@ func (renderer blockRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
}
|
||||
|
||||
if unchangedAttributes > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("attribute", unchangedAttributes)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("attribute", unchangedAttributes)))
|
||||
}
|
||||
|
||||
var blockKeys []string
|
||||
@ -118,9 +114,9 @@ func (renderer blockRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
}
|
||||
|
||||
if unchangedBlocks > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("block", unchangedBlocks)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("block", unchangedBlocks)))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s%s }", change.indent(indent), change.emptySymbol()))
|
||||
buf.WriteString(fmt.Sprintf("%s%s }", change.indent(indent), format.DiffActionSymbol(plans.NoOp)))
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ func (change Change) Warnings(indent int) []string {
|
||||
return change.renderer.Warnings(change, indent)
|
||||
}
|
||||
|
||||
// GetAction returns the plans.Action that this change describes.
|
||||
func (change Change) GetAction() plans.Action {
|
||||
// Action returns the plans.Action that this change describes.
|
||||
func (change Change) Action() plans.Action {
|
||||
return change.action
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ func (renderer listRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
// minus 1 as the most recent unchanged element will be printed out
|
||||
// in full.
|
||||
if len(unchangedElements) > 1 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("element", len(unchangedElements)-1)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("element", len(unchangedElements)-1)))
|
||||
}
|
||||
// If our list of unchanged elements contains at least one entry,
|
||||
// we're going to print out the most recent change in full. That's
|
||||
@ -95,11 +95,7 @@ func (renderer listRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
for _, warning := range element.Warnings(indent + 1) {
|
||||
buf.WriteString(fmt.Sprintf("%s%s\n", change.indent(indent+1), warning))
|
||||
}
|
||||
if element.action == plans.NoOp {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s,\n", change.indent(indent+1), element.emptySymbol(), element.Render(indent+1, unchangedElementOpts)))
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s,\n", change.indent(indent+1), format.DiffActionSymbol(element.action), element.Render(indent+1, elementOpts)))
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s,\n", change.indent(indent+1), format.DiffActionSymbol(element.action), element.Render(indent+1, elementOpts)))
|
||||
}
|
||||
|
||||
// If we were not displaying any context alongside our changes then the
|
||||
@ -109,9 +105,9 @@ func (renderer listRenderer) Render(change Change, indent int, opts RenderOpts)
|
||||
// If we were displaying context, then this will contain any unchanged
|
||||
// elements since our last change, so we should also print it out.
|
||||
if len(unchangedElements) > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("element", len(unchangedElements))))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("element", len(unchangedElements))))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s%s ]%s", change.indent(indent), change.emptySymbol(), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s ]%s", change.indent(indent), format.DiffActionSymbol(plans.NoOp), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ func (renderer mapRenderer) Render(change Change, indent int, opts RenderOpts) s
|
||||
}
|
||||
|
||||
if unchangedElements > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("element", unchangedElements)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("element", unchangedElements)))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s%s }%s", change.indent(indent), change.emptySymbol(), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s }%s", change.indent(indent), format.DiffActionSymbol(plans.NoOp), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -80,9 +80,9 @@ func (renderer objectRenderer) Render(change Change, indent int, opts RenderOpts
|
||||
}
|
||||
|
||||
if unchangedAttributes > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("attribute", unchangedAttributes)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("attribute", unchangedAttributes)))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s%s }%s", change.indent(indent), change.emptySymbol(), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s }%s", change.indent(indent), format.DiffActionSymbol(plans.NoOp), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ func (renderer setRenderer) Render(change Change, indent int, opts RenderOpts) s
|
||||
}
|
||||
|
||||
if unchangedElements > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("element", unchangedElements)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), format.DiffActionSymbol(plans.NoOp), change.unchanged("element", unchangedElements)))
|
||||
}
|
||||
|
||||
buf.WriteString(fmt.Sprintf("%s%s ]%s", change.indent(indent), change.emptySymbol(), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
buf.WriteString(fmt.Sprintf("%s%s ]%s", change.indent(indent), format.DiffActionSymbol(plans.NoOp), change.nullSuffix(opts.overrideNullSuffix)))
|
||||
return buf.String()
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ func (v Value) computeChangeForNestedAttribute(nested *jsonprovider.NestedType)
|
||||
return computed
|
||||
}
|
||||
|
||||
switch nested.NestingMode {
|
||||
case "single", "group":
|
||||
switch NestingMode(nested.NestingMode) {
|
||||
case nestingModeSingle, nestingModeGroup:
|
||||
return v.computeAttributeChangeAsNestedObject(nested.Attributes)
|
||||
case "map":
|
||||
case nestingModeMap:
|
||||
return v.computeAttributeChangeAsNestedMap(nested.Attributes)
|
||||
case "list":
|
||||
case nestingModeList:
|
||||
return v.computeAttributeChangeAsNestedList(nested.Attributes)
|
||||
case "set":
|
||||
case nestingModeSet:
|
||||
return v.computeAttributeChangeAsNestedSet(nested.Attributes)
|
||||
default:
|
||||
panic("unrecognized nesting mode: " + nested.NestingMode)
|
||||
|
@ -23,13 +23,13 @@ func (v Value) ComputeChangeForBlock(block *jsonprovider.Block) change.Change {
|
||||
for key, attr := range block.Attributes {
|
||||
childValue := blockValue.getChild(key)
|
||||
childChange := childValue.ComputeChangeForAttribute(attr)
|
||||
if childChange.GetAction() == plans.NoOp && childValue.Before == nil && childValue.After == nil {
|
||||
if childChange.Action() == plans.NoOp && childValue.Before == nil && childValue.After == nil {
|
||||
// Don't record nil values at all in blocks.
|
||||
continue
|
||||
}
|
||||
|
||||
attributes[key] = childChange
|
||||
current = compareActions(current, childChange.GetAction())
|
||||
current = compareActions(current, childChange.Action())
|
||||
}
|
||||
|
||||
blocks := make(map[string][]change.Change)
|
||||
@ -48,16 +48,16 @@ func (v Value) ComputeChangeForBlock(block *jsonprovider.Block) change.Change {
|
||||
}
|
||||
|
||||
func (v Value) computeChangesForBlockType(blockType *jsonprovider.BlockType) ([]change.Change, plans.Action) {
|
||||
switch blockType.NestingMode {
|
||||
case "set":
|
||||
switch NestingMode(blockType.NestingMode) {
|
||||
case nestingModeSet:
|
||||
return v.computeBlockChangesAsSet(blockType.Block)
|
||||
case "list":
|
||||
case nestingModeList:
|
||||
return v.computeBlockChangesAsList(blockType.Block)
|
||||
case "map":
|
||||
case nestingModeMap:
|
||||
return v.computeBlockChangesAsMap(blockType.Block)
|
||||
case "single", "group":
|
||||
case nestingModeSingle, nestingModeGroup:
|
||||
ch := v.ComputeChangeForBlock(blockType.Block)
|
||||
return []change.Change{ch}, ch.GetAction()
|
||||
return []change.Change{ch}, ch.Action()
|
||||
default:
|
||||
panic("unrecognized nesting mode: " + blockType.NestingMode)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ func (v Value) computeAttributeChangeAsList(elementType cty.Type) change.Change
|
||||
v.processList(elementType.IsObjectType(), func(value Value) {
|
||||
element := value.computeChangeForType(elementType)
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.List(elements), current, v.replacePath())
|
||||
}
|
||||
@ -30,7 +30,7 @@ func (v Value) computeAttributeChangeAsNestedList(attributes map[string]*jsonpro
|
||||
NestingMode: "single",
|
||||
})
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.NestedList(elements), current, v.replacePath())
|
||||
}
|
||||
@ -41,7 +41,7 @@ func (v Value) computeBlockChangesAsList(block *jsonprovider.Block) ([]change.Ch
|
||||
v.processNestedList(func(value Value) {
|
||||
element := value.ComputeChangeForBlock(block)
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return elements, current
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ func (v Value) computeAttributeChangeAsMap(elementType cty.Type) change.Change {
|
||||
v.processMap(func(key string, value Value) {
|
||||
element := value.computeChangeForType(elementType)
|
||||
elements[key] = element
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.Map(elements), current, v.replacePath())
|
||||
}
|
||||
@ -28,7 +28,7 @@ func (v Value) computeAttributeChangeAsNestedMap(attributes map[string]*jsonprov
|
||||
NestingMode: "single",
|
||||
})
|
||||
elements[key] = element
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.Map(elements), current, v.replacePath())
|
||||
}
|
||||
@ -39,7 +39,7 @@ func (v Value) computeBlockChangesAsMap(block *jsonprovider.Block) ([]change.Cha
|
||||
v.processMap(func(key string, value Value) {
|
||||
element := value.ComputeChangeForBlock(block)
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return elements, current
|
||||
}
|
||||
|
@ -48,13 +48,13 @@ func processObject[T any](v Value, attributes map[string]T, computeChange func(V
|
||||
// We use the generic ComputeChange here, as we don't know whether this
|
||||
// is from a nested object or a `normal` object.
|
||||
attributeChange := computeChange(attributeValue, attribute)
|
||||
if attributeChange.GetAction() == plans.NoOp && attributeValue.Before == nil && attributeValue.After == nil {
|
||||
if attributeChange.Action() == plans.NoOp && attributeValue.Before == nil && attributeValue.After == nil {
|
||||
// We skip attributes of objects that are null both before and
|
||||
// after. We don't even count these as unchanged attributes.
|
||||
continue
|
||||
}
|
||||
attributeChanges[key] = attributeChange
|
||||
currentAction = compareActions(currentAction, attributeChange.GetAction())
|
||||
currentAction = compareActions(currentAction, attributeChange.Action())
|
||||
}
|
||||
|
||||
return attributeChanges, currentAction
|
||||
|
@ -9,15 +9,6 @@ import (
|
||||
"github.com/hashicorp/terraform/internal/plans"
|
||||
)
|
||||
|
||||
const (
|
||||
jsonNumber = "number"
|
||||
jsonObject = "object"
|
||||
jsonArray = "array"
|
||||
jsonBool = "bool"
|
||||
jsonString = "string"
|
||||
jsonNull = "null"
|
||||
)
|
||||
|
||||
func (v Value) ComputeChangeForOutput() change.Change {
|
||||
if sensitive, ok := v.checkForSensitive(); ok {
|
||||
return sensitive
|
||||
@ -30,7 +21,7 @@ func (v Value) ComputeChangeForOutput() change.Change {
|
||||
beforeType := getJsonType(v.Before)
|
||||
afterType := getJsonType(v.After)
|
||||
|
||||
valueToAttribute := func(v Value, jsonType string) change.Change {
|
||||
valueToAttribute := func(v Value, jsonType JsonType) change.Change {
|
||||
var res change.Change
|
||||
|
||||
switch jsonType {
|
||||
@ -75,7 +66,7 @@ func (v Value) ComputeChangeForOutput() change.Change {
|
||||
return change.New(change.TypeChange(before, after), plans.Update, false)
|
||||
}
|
||||
|
||||
func getJsonType(json interface{}) string {
|
||||
func getJsonType(json interface{}) JsonType {
|
||||
switch json.(type) {
|
||||
case []interface{}:
|
||||
return jsonArray
|
||||
|
@ -16,7 +16,7 @@ func (v Value) computeAttributeChangeAsSet(elementType cty.Type) change.Change {
|
||||
v.processSet(false, func(value Value) {
|
||||
element := value.computeChangeForType(elementType)
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.Set(elements), current, v.replacePath())
|
||||
}
|
||||
@ -30,7 +30,7 @@ func (v Value) computeAttributeChangeAsNestedSet(attributes map[string]*jsonprov
|
||||
NestingMode: "single",
|
||||
})
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return change.New(change.Set(elements), current, v.replacePath())
|
||||
}
|
||||
@ -41,7 +41,7 @@ func (v Value) computeBlockChangesAsSet(block *jsonprovider.Block) ([]change.Cha
|
||||
v.processSet(true, func(value Value) {
|
||||
element := value.ComputeChangeForBlock(block)
|
||||
elements = append(elements, element)
|
||||
current = compareActions(current, element.GetAction())
|
||||
current = compareActions(current, element.Action())
|
||||
})
|
||||
return elements, current
|
||||
}
|
||||
|
25
internal/command/jsonformat/differ/types.go
Normal file
25
internal/command/jsonformat/differ/types.go
Normal file
@ -0,0 +1,25 @@
|
||||
package differ
|
||||
|
||||
// JsonType is a wrapper around a string type to describe the various different
|
||||
// kinds of JSON types. This is used when processing dynamic types and outputs.
|
||||
type JsonType string
|
||||
|
||||
// NestingMode is a wrapper around a string type to describe the various
|
||||
// different kinds of nesting modes that can be applied to nested blocks and
|
||||
// objects.
|
||||
type NestingMode string
|
||||
|
||||
const (
|
||||
jsonNumber JsonType = "number"
|
||||
jsonObject JsonType = "object"
|
||||
jsonArray JsonType = "array"
|
||||
jsonBool JsonType = "bool"
|
||||
jsonString JsonType = "string"
|
||||
jsonNull JsonType = "null"
|
||||
|
||||
nestingModeSet NestingMode = "set"
|
||||
nestingModeList NestingMode = "list"
|
||||
nestingModeMap NestingMode = "map"
|
||||
nestingModeSingle NestingMode = "single"
|
||||
nestingModeGroup NestingMode = "group"
|
||||
)
|
Loading…
Reference in New Issue
Block a user