don't add duplicate unknowns to a set

The flatmap shim was lazily adding duplicate items and letting cty.Set
clear them out, but if those duplicates contains unknown values they
can't be checked for equality and will end up remaining in the set.
This commit is contained in:
James Bardin 2018-11-08 18:01:39 -05:00
parent ebc9745788
commit 6fee1f24ab
2 changed files with 56 additions and 0 deletions

View File

@ -356,6 +356,11 @@ func hcl2ValueFromFlatmapSet(m map[string]string, prefix string, ty cty.Type) (c
return cty.UnknownVal(ty), nil return cty.UnknownVal(ty), nil
} }
// Keep track of keys we've seen, se we don't add the same set value
// multiple times. The cty.Set will normally de-duplicate values, but we may
// have unknown values that would not show as equivalent.
seen := map[string]bool{}
for fullKey := range m { for fullKey := range m {
if !strings.HasPrefix(fullKey, prefix) { if !strings.HasPrefix(fullKey, prefix) {
continue continue
@ -370,6 +375,12 @@ func hcl2ValueFromFlatmapSet(m map[string]string, prefix string, ty cty.Type) (c
key = fullKey[:dot+len(prefix)] key = fullKey[:dot+len(prefix)]
} }
if seen[key] {
continue
}
seen[key] = true
// The flatmap format doesn't allow us to distinguish between keys // The flatmap format doesn't allow us to distinguish between keys
// that contain periods and nested objects, so by convention a // that contain periods and nested objects, so by convention a
// map is only ever of primitive type in flatmap, and we just assume // map is only ever of primitive type in flatmap, and we just assume
@ -386,5 +397,6 @@ func hcl2ValueFromFlatmapSet(m map[string]string, prefix string, ty cty.Type) (c
if len(vals) == 0 { if len(vals) == 0 {
return cty.SetValEmpty(ety), nil return cty.SetValEmpty(ety), nil
} }
return cty.SetVal(vals), nil return cty.SetVal(vals), nil
} }

View File

@ -635,6 +635,50 @@ func TestHCL2ValueFromFlatmap(t *testing.T) {
}), }),
}), }),
}, },
{
Flatmap: map[string]string{
"single.#": "1",
"single.~1.value": "a",
"single.~1.optional": UnknownVariableValue,
"two.#": "2",
"two.~2381914684.value": "a",
"two.~2381914684.optional": UnknownVariableValue,
"two.~2798940671.value": "b",
"two.~2798940671.optional": UnknownVariableValue,
},
Type: cty.Object(map[string]cty.Type{
"single": cty.Set(
cty.Object(map[string]cty.Type{
"value": cty.String,
"optional": cty.String,
}),
),
"two": cty.Set(
cty.Object(map[string]cty.Type{
"optional": cty.String,
"value": cty.String,
}),
),
}),
Want: cty.ObjectVal(map[string]cty.Value{
"single": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"value": cty.StringVal("a"),
"optional": cty.UnknownVal(cty.String),
}),
}),
"two": cty.SetVal([]cty.Value{
cty.ObjectVal(map[string]cty.Value{
"value": cty.StringVal("a"),
"optional": cty.UnknownVal(cty.String),
}),
cty.ObjectVal(map[string]cty.Value{
"value": cty.StringVal("b"),
"optional": cty.UnknownVal(cty.String),
}),
}),
}),
},
} }
for _, test := range tests { for _, test := range tests {