From 12a7448eb23fad775cb0ab0a839a454760017046 Mon Sep 17 00:00:00 2001 From: "Giau. Tran Minh" <12751435+giautm@users.noreply.github.com> Date: Wed, 6 Dec 2023 14:56:45 +0700 Subject: [PATCH] schemahcl: children (context) can refuse inheritance (#2334) * schemahcl: children (context) can refuse inheritance * schemahcl: added test for ScopeContextOverride --- schemahcl/schemahcl.go | 15 ++++++++------- schemahcl/schemahcl_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) 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]) +}