mirror of https://github.com/hashicorp/terraform
Add support for blocks in the structured renderer (#32422)
* prep for processing the structured run output * undo unwanted change to a json key * Add skeleton functions and API for refactored renderer * goimports * Fix documentation of the RenderOpts struct * Add rendering functionality for primitives to the structured renderer * add test case for override * Add support for parsing and rendering sensitive values in the renderer * Add support for unknown/computed values in the structured renderer * delete missing unit tests * Add support for object attributes in the structured renderer * goimports * Add support for the replace paths data in the structured renderer * Add support for maps in the structured renderer * Add support for lists in the structured renderer * goimports * Add support for sets in the structured renderer * goimports * Add support for blocks in the structured renderer * goimports * fix ordering of blocks * remove unused test stubpull/32426/head
parent
69cce3597f
commit
05f1764a0d
@ -0,0 +1,126 @@
|
||||
package change
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/terraform/internal/command/format"
|
||||
"github.com/hashicorp/terraform/internal/plans"
|
||||
)
|
||||
|
||||
var (
|
||||
importantAttributes = []string{
|
||||
"id",
|
||||
}
|
||||
)
|
||||
|
||||
func importantAttribute(attr string) bool {
|
||||
for _, attribute := range importantAttributes {
|
||||
if attribute == attr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func Block(attributes map[string]Change, blocks map[string][]Change) Renderer {
|
||||
maximumKeyLen := 0
|
||||
for key := range attributes {
|
||||
if len(key) > maximumKeyLen {
|
||||
maximumKeyLen = len(key)
|
||||
}
|
||||
}
|
||||
|
||||
return &blockRenderer{
|
||||
attributes: attributes,
|
||||
blocks: blocks,
|
||||
maximumKeyLen: maximumKeyLen,
|
||||
}
|
||||
}
|
||||
|
||||
type blockRenderer struct {
|
||||
NoWarningsRenderer
|
||||
|
||||
attributes map[string]Change
|
||||
blocks map[string][]Change
|
||||
maximumKeyLen int
|
||||
}
|
||||
|
||||
func (renderer blockRenderer) Render(change Change, indent int, opts RenderOpts) string {
|
||||
unchangedAttributes := 0
|
||||
unchangedBlocks := 0
|
||||
|
||||
var buf bytes.Buffer
|
||||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
var attributeKeys []string
|
||||
for key := range renderer.attributes {
|
||||
attributeKeys = append(attributeKeys, key)
|
||||
}
|
||||
sort.Strings(attributeKeys)
|
||||
|
||||
for _, key := range attributeKeys {
|
||||
if importantAttribute(key) {
|
||||
continue
|
||||
}
|
||||
attribute := renderer.attributes[key]
|
||||
if attribute.action == plans.NoOp && !opts.showUnchangedChildren {
|
||||
unchangedAttributes++
|
||||
continue
|
||||
}
|
||||
|
||||
for _, warning := range attribute.Warnings(indent + 1) {
|
||||
buf.WriteString(fmt.Sprintf("%s%s\n", change.indent(indent+1), warning))
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%s%s %-*s = %s\n", change.indent(indent+1), format.DiffActionSymbol(attribute.action), renderer.maximumKeyLen, key, attribute.Render(indent+1, opts)))
|
||||
}
|
||||
|
||||
if unchangedAttributes > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s\n", change.indent(indent+1), change.emptySymbol(), change.unchanged("attribute", unchangedAttributes)))
|
||||
}
|
||||
|
||||
var blockKeys []string
|
||||
for key := range renderer.blocks {
|
||||
blockKeys = append(blockKeys, key)
|
||||
}
|
||||
sort.Strings(blockKeys)
|
||||
|
||||
for _, key := range blockKeys {
|
||||
blocks := renderer.blocks[key]
|
||||
|
||||
foundChangedBlock := false
|
||||
for _, block := range blocks {
|
||||
if block.action == plans.NoOp && !opts.showUnchangedChildren {
|
||||
unchangedBlocks++
|
||||
continue
|
||||
}
|
||||
|
||||
if !foundChangedBlock && len(renderer.attributes) > 0 {
|
||||
buf.WriteString("\n")
|
||||
foundChangedBlock = true
|
||||
}
|
||||
|
||||
for _, warning := range block.Warnings(indent + 1) {
|
||||
buf.WriteString(fmt.Sprintf("%s%s\n", change.indent(indent+1), warning))
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%s%s %s %s\n", change.indent(indent+1), format.DiffActionSymbol(block.action), key, block.Render(indent+1, opts)))
|
||||
}
|
||||
}
|
||||
|
||||
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 }", change.indent(indent), change.emptySymbol()))
|
||||
return buf.String()
|
||||
}
|
||||
Loading…
Reference in new issue