diff --git a/schemahcl/schemahcl.go b/schemahcl/schemahcl.go index 41db66e0cfb..fbd28af0f9a 100644 --- a/schemahcl/schemahcl.go +++ b/schemahcl/schemahcl.go @@ -483,6 +483,14 @@ func (s *State) mayScopeContext(ctx *hcl.EvalContext, scope []string) *hcl.EvalC Variables: make(map[string]cty.Value), Functions: make(map[string]function.Function), } + for p := ctx; p != nil; p = p.Parent() { + for k, v := range p.Variables { + if isRef(v) { + nctx.Variables[k] = v + } + } + } + // Override the parent context with the scoped variables and functions. for n, v := range vars { nctx.Variables[n] = v } @@ -492,13 +500,6 @@ func (s *State) mayScopeContext(ctx *hcl.EvalContext, scope []string) *hcl.EvalC // A patch from the past. Should be moved // to specific scopes in the future. nctx.Functions["sql"] = rawExprFunc - for p := ctx; p != nil; p = p.Parent() { - for k, v := range p.Variables { - if isRef(v) { - nctx.Variables[k] = v - } - } - } return nctx } diff --git a/schemahcl/schemahcl_test.go b/schemahcl/schemahcl_test.go index ece7a010de0..1928318d34d 100644 --- a/schemahcl/schemahcl_test.go +++ b/schemahcl/schemahcl_test.go @@ -949,3 +949,39 @@ foo "f1" { }, }, &e) } + +func Test_ScopeContextOverride(t *testing.T) { + type ( + Foo struct { + Name string `spec:",name"` + } + Bar struct { + Name string `spec:",name"` + Attr string `spec:"attr"` + Ref *Ref `spec:"ref"` + } + ) + var ( + doc struct { + Foo []*Foo `spec:"foo"` + Bar []*Bar `spec:"bar"` + } + b = []byte(` +foo "f1" {} +bar "b1" { + attr = foo + ref = foo.f1 +} +`) + ) + require.NoError(t, New( + WithScopedEnums("bar.attr", "foo"), // foo is a valid value for bar.attr. + ).EvalBytes(b, &doc, nil)) + require.Len(t, doc.Foo, 1) + require.Len(t, doc.Bar, 1) + require.Equal(t, &Bar{ + Name: "b1", + Attr: "foo", + Ref: &Ref{V: "$foo.f1"}, + }, doc.Bar[0]) +}