helper/schema: write "attr.#": "0" for empty maps

This fixes some perpetual diffs I saw in Atlas AccTests where an empty
map (`map[string]interface{}{}`) was being `d.Set` for "metadata_full".

Because the MapFieldWriter was not distinguishing between empty and nil,
this trigger the "map delete" logic and no count was written to the
state. This caused subsequent plans to improperly report a diff.

Here we redefine the map delete functionality to explicitly trigger only
on `nil`, so we catch the `.#` field for empty maps.
pull/1824/head
Paul Hinze 11 years ago
parent 010a39a58e
commit f2368428d3

@ -141,25 +141,23 @@ func (w *MapFieldWriter) setMap(
v := reflect.ValueOf(value)
vs := make(map[string]interface{})
if value != nil {
if v.Kind() != reflect.Map {
return fmt.Errorf("%s: must be a map", k)
}
if v.Type().Key().Kind() != reflect.String {
return fmt.Errorf("%s: keys must strings", k)
}
for _, mk := range v.MapKeys() {
mv := v.MapIndex(mk)
vs[mk.String()] = mv.Interface()
}
}
if len(vs) == 0 {
if value == nil {
// The empty string here means the map is removed.
w.result[k] = ""
return nil
}
if v.Kind() != reflect.Map {
return fmt.Errorf("%s: must be a map", k)
}
if v.Type().Key().Kind() != reflect.String {
return fmt.Errorf("%s: keys must strings", k)
}
for _, mk := range v.MapKeys() {
mv := v.MapIndex(mk)
vs[mk.String()] = mv.Interface()
}
// Remove the pure key since we're setting the full map value
delete(w.result, k)

@ -2539,7 +2539,9 @@ func TestResourceDataState(t *testing.T) {
},
Result: &terraform.InstanceState{
Attributes: map[string]string{},
Attributes: map[string]string{
"tags.#": "0",
},
},
},

Loading…
Cancel
Save