diff --git a/gohcl/decode.go b/gohcl/decode.go index 3525383..302a3f4 100644 --- a/gohcl/decode.go +++ b/gohcl/decode.go @@ -198,6 +198,9 @@ func decodeBodyToStruct(body hcl.Body, ctx *hcl.EvalContext, val reflect.Value) diags = append(diags, decodeBlockToValue(block, ctx, v.Elem())...) sli.Index(i).Set(v) } else { + if i >= sli.Len() { + sli = reflect.Append(sli, reflect.Indirect(reflect.New(ty))) + } diags = append(diags, decodeBlockToValue(block, ctx, sli.Index(i))...) } } diff --git a/gohcl/decode_test.go b/gohcl/decode_test.go index 0927490..50eaea7 100644 --- a/gohcl/decode_test.go +++ b/gohcl/decode_test.go @@ -37,6 +37,10 @@ func TestDecodeBody(t *testing.T) { Nested []*withTwoAttributes `hcl:"nested,block"` } + type withListofNestedBlocksNoPointers struct { + Nested []withTwoAttributes `hcl:"nested,block"` + } + tests := []struct { Body map[string]interface{} Target func() interface{} @@ -647,6 +651,33 @@ func TestDecodeBody(t *testing.T) { }, 0, }, + { + // Make sure decoding value slices works the same as pointer slices. + map[string]interface{}{ + "nested": []map[string]interface{}{ + { + "b": "bar", + }, + { + "b": "baz", + }, + }, + }, + func() interface{} { + return &withListofNestedBlocksNoPointers{ + Nested: []withTwoAttributes{ + { + B: "foo", + }, + }, + } + }, + func(gotI interface{}) bool { + n := gotI.(withListofNestedBlocksNoPointers) + return n.Nested[0].B == "bar" && len(n.Nested) == 2 + }, + 0, + }, } for i, test := range tests {