From bebd6ba7fff5d3810e8d1e7a2ec61687e02a5590 Mon Sep 17 00:00:00 2001 From: Seth Vargo Date: Thu, 10 Mar 2016 14:04:52 -0500 Subject: [PATCH] Ensure top-level object literals are arrays Fixes GH-60 --- decoder.go | 8 ++++++++ decoder_test.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/decoder.go b/decoder.go index b0c3fc6..3d6b762 100644 --- a/decoder.go +++ b/decoder.go @@ -466,6 +466,14 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) node = ot.List } + // Handle the special case where the object itself is a literal. Previously + // the yacc parser would always ensure top-level elements were arrays. The new + // parser does not make the same guarantees, thus we need to convert any + // top-level literal elements into a list. + if _, ok := node.(*ast.LiteralType); ok { + node = &ast.ObjectList{Items: []*ast.ObjectItem{item}} + } + list, ok := node.(*ast.ObjectList) if !ok { return &parser.PosError{ diff --git a/decoder_test.go b/decoder_test.go index e976271..8ab8596 100644 --- a/decoder_test.go +++ b/decoder_test.go @@ -667,3 +667,35 @@ nested "content" { t.Errorf("expected mapping to be returned") } } + +// https://github.com/hashicorp/hcl/issues/60 +func TestDecode_topLevelKeys(t *testing.T) { + type Template struct { + Source string + } + + templates := struct { + Templates []*Template `hcl:"template"` + }{} + + err := Decode(&templates, ` + template { + source = "blah" + } + + template { + source = "blahblah" + }`) + + if err != nil { + t.Fatal(err) + } + + if templates.Templates[0].Source != "blah" { + t.Errorf("bad source: %s", templates.Templates[0].Source) + } + + if templates.Templates[1].Source != "blahblah" { + t.Errorf("bad source: %s", templates.Templates[1].Source) + } +}