Merge pull request #20067 from hashicorp/b-cmd-fmt-unknown-set
command/format: Fix rendering of unknown elements in set/map/list
This commit is contained in:
commit
7e0be7d8b9
|
@ -377,6 +377,9 @@ func (p *blockBodyDiffPrinter) writeNestedBlockDiffs(name string, blockS *config
|
||||||
var action plans.Action
|
var action plans.Action
|
||||||
var oldValue, newValue cty.Value
|
var oldValue, newValue cty.Value
|
||||||
switch {
|
switch {
|
||||||
|
case !val.IsKnown():
|
||||||
|
action = plans.Update
|
||||||
|
newValue = val
|
||||||
case !old.HasElement(val).True():
|
case !old.HasElement(val).True():
|
||||||
action = plans.Create
|
action = plans.Create
|
||||||
oldValue = cty.NullVal(val.Type())
|
oldValue = cty.NullVal(val.Type())
|
||||||
|
@ -697,7 +700,7 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
||||||
for it := new.ElementIterator(); it.Next(); {
|
for it := new.ElementIterator(); it.Next(); {
|
||||||
_, val := it.Element()
|
_, val := it.Element()
|
||||||
allVals = append(allVals, val)
|
allVals = append(allVals, val)
|
||||||
if old.HasElement(val).False() {
|
if val.IsKnown() && old.HasElement(val).False() {
|
||||||
addedVals = append(addedVals, val)
|
addedVals = append(addedVals, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,6 +729,8 @@ func (p *blockBodyDiffPrinter) writeValueDiff(old, new cty.Value, indent int, pa
|
||||||
|
|
||||||
var action plans.Action
|
var action plans.Action
|
||||||
switch {
|
switch {
|
||||||
|
case !val.IsKnown():
|
||||||
|
action = plans.Update
|
||||||
case added.HasElement(val).True():
|
case added.HasElement(val).True():
|
||||||
action = plans.Create
|
action = plans.Create
|
||||||
case removed.HasElement(val).True():
|
case removed.HasElement(val).True():
|
||||||
|
@ -1062,7 +1067,7 @@ func ctyObjectSimilarity(old, new cty.Value) float64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ctyEqualWithUnknown(old, new cty.Value) bool {
|
func ctyEqualWithUnknown(old, new cty.Value) bool {
|
||||||
if !old.IsKnown() || !new.IsKnown() {
|
if !old.IsWhollyKnown() || !new.IsWhollyKnown() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return old.Equals(new).True()
|
return old.Equals(new).True()
|
||||||
|
|
|
@ -720,6 +720,92 @@ func TestResourceChange_primitiveList(t *testing.T) {
|
||||||
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
+ list_field = []
|
+ list_field = []
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"update to unknown element": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"list_field": {Type: cty.List(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ list_field = [
|
||||||
|
"aaaa",
|
||||||
|
- "bbbb",
|
||||||
|
+ (known after apply),
|
||||||
|
"cccc",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"update - two new unknown elements": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"list_field": {Type: cty.List(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ list_field = [
|
||||||
|
"aaaa",
|
||||||
|
- "bbbb",
|
||||||
|
+ (known after apply),
|
||||||
|
+ (known after apply),
|
||||||
|
"cccc",
|
||||||
|
]
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1002,6 +1088,80 @@ func TestResourceChange_primitiveSet(t *testing.T) {
|
||||||
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
+ set_field = []
|
+ set_field = []
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"in-place update to unknown": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.SetVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.UnknownVal(cty.Set(cty.String)),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"set_field": {Type: cty.Set(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ set_field = [
|
||||||
|
- "aaaa",
|
||||||
|
- "bbbb",
|
||||||
|
] -> (known after apply)
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"in-place update to unknown element": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.SetVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.SetVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.UnknownVal(cty.String),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"set_field": {Type: cty.Set(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ set_field = [
|
||||||
|
"aaaa",
|
||||||
|
- "bbbb",
|
||||||
|
~ (known after apply),
|
||||||
|
]
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1220,6 +1380,47 @@ func TestResourceChange_map(t *testing.T) {
|
||||||
+ id = (known after apply)
|
+ id = (known after apply)
|
||||||
+ map_field = {}
|
+ map_field = {}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"update to unknown element": {
|
||||||
|
Action: plans.Update,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"map_field": cty.MapVal(map[string]cty.Value{
|
||||||
|
"a": cty.StringVal("aaaa"),
|
||||||
|
"b": cty.StringVal("bbbb"),
|
||||||
|
"c": cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"map_field": cty.MapVal(map[string]cty.Value{
|
||||||
|
"a": cty.StringVal("aaaa"),
|
||||||
|
"b": cty.UnknownVal(cty.String),
|
||||||
|
"c": cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"map_field": {Type: cty.Map(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(),
|
||||||
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
||||||
|
~ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ map_field = {
|
||||||
|
"a" = "aaaa"
|
||||||
|
~ "b" = "bbbb" -> (known after apply)
|
||||||
|
"c" = "cccc"
|
||||||
|
}
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue