render empty nested containers as attributes

Don't try to break down containers that are empty to render the diff, so
we can avoid having to check for empty vs null in all cases.
This commit is contained in:
James Bardin 2021-08-16 18:13:55 -04:00
parent 8407ce73db
commit fbfb14142e
2 changed files with 58 additions and 2 deletions

View File

@ -471,8 +471,28 @@ func (p *blockBodyDiffPrinter) writeAttrDiff(name string, attrS *configschema.At
} }
if attrS.NestedType != nil { if attrS.NestedType != nil {
p.writeNestedAttrDiff(name, attrS.NestedType, old, new, nameLen, indent, path, action, showJustNew) renderNested := true
return false
// If the collection values are empty or null, we render them as single attributes
switch attrS.NestedType.Nesting {
case configschema.NestingList, configschema.NestingSet, configschema.NestingMap:
var oldLen, newLen int
if !old.IsNull() && old.IsKnown() {
oldLen = old.LengthInt()
}
if !new.IsNull() && new.IsKnown() {
newLen = new.LengthInt()
}
if oldLen+newLen == 0 {
renderNested = false
}
}
if renderNested {
p.writeNestedAttrDiff(name, attrS.NestedType, old, new, nameLen, indent, path, action, showJustNew)
return false
}
} }
p.buf.WriteString("\n") p.buf.WriteString("\n")
@ -613,6 +633,7 @@ func (p *blockBodyDiffPrinter) writeNestedAttrDiff(
allItems := make([]cty.Value, 0, len(oldItems)+len(newItems)) allItems := make([]cty.Value, 0, len(oldItems)+len(newItems))
allItems = append(allItems, oldItems...) allItems = append(allItems, oldItems...)
allItems = append(allItems, newItems...) allItems = append(allItems, newItems...)
all := cty.SetVal(allItems) all := cty.SetVal(allItems)
p.buf.WriteString(" = [") p.buf.WriteString(" = [")

View File

@ -2861,6 +2861,41 @@ func TestResourceChange_nestedSet(t *testing.T) {
- volume_type = "gp2" -> null - volume_type = "gp2" -> null
} }
} }
`,
},
"in-place update - empty nested sets": {
Action: plans.Update,
Mode: addrs.ManagedResourceMode,
Before: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("i-02ae66f368e8518a9"),
"ami": cty.StringVal("ami-BEFORE"),
"disks": cty.NullVal(cty.Set(cty.Object(map[string]cty.Type{
"mount_point": cty.String,
"size": cty.String,
}))),
"root_block_device": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"volume_type": cty.String,
})),
}),
After: cty.ObjectVal(map[string]cty.Value{
"id": cty.StringVal("i-02ae66f368e8518a9"),
"ami": cty.StringVal("ami-AFTER"),
"disks": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"mount_point": cty.String,
"size": cty.String,
})),
"root_block_device": cty.SetValEmpty(cty.Object(map[string]cty.Type{
"volume_type": cty.String,
})),
}),
RequiredReplace: cty.NewPathSet(),
Schema: testSchema(configschema.NestingSet),
ExpectedOutput: ` # test_instance.example will be updated in-place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" -> "ami-AFTER"
+ disks = []
id = "i-02ae66f368e8518a9"
}
`, `,
}, },
} }