config: parsing of local.foo variables for interpolation
This commit is contained in:
parent
f6797d6cb0
commit
d41d58967f
|
@ -101,6 +101,12 @@ type UserVariable struct {
|
||||||
key string
|
key string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A LocalVariable is a variable that references a local value defined within
|
||||||
|
// the current module, via a "locals" block. This looks like "${local.foo}".
|
||||||
|
type LocalVariable struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
|
func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
|
||||||
if strings.HasPrefix(v, "count.") {
|
if strings.HasPrefix(v, "count.") {
|
||||||
return NewCountVariable(v)
|
return NewCountVariable(v)
|
||||||
|
@ -112,6 +118,8 @@ func NewInterpolatedVariable(v string) (InterpolatedVariable, error) {
|
||||||
return NewTerraformVariable(v)
|
return NewTerraformVariable(v)
|
||||||
} else if strings.HasPrefix(v, "var.") {
|
} else if strings.HasPrefix(v, "var.") {
|
||||||
return NewUserVariable(v)
|
return NewUserVariable(v)
|
||||||
|
} else if strings.HasPrefix(v, "local.") {
|
||||||
|
return NewLocalVariable(v)
|
||||||
} else if strings.HasPrefix(v, "module.") {
|
} else if strings.HasPrefix(v, "module.") {
|
||||||
return NewModuleVariable(v)
|
return NewModuleVariable(v)
|
||||||
} else if !strings.ContainsRune(v, '.') {
|
} else if !strings.ContainsRune(v, '.') {
|
||||||
|
@ -331,6 +339,25 @@ func (v *UserVariable) GoString() string {
|
||||||
return fmt.Sprintf("*%#v", *v)
|
return fmt.Sprintf("*%#v", *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewLocalVariable(key string) (*LocalVariable, error) {
|
||||||
|
name := key[len("local."):]
|
||||||
|
if idx := strings.Index(name, "."); idx > -1 {
|
||||||
|
return nil, fmt.Errorf("Can't use dot (.) attribute access in local.%s; use square bracket indexing", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &LocalVariable{
|
||||||
|
Name: name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *LocalVariable) FullKey() string {
|
||||||
|
return fmt.Sprintf("local.%s", v.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *LocalVariable) GoString() string {
|
||||||
|
return fmt.Sprintf("*%#v", *v)
|
||||||
|
}
|
||||||
|
|
||||||
// DetectVariables takes an AST root and returns all the interpolated
|
// DetectVariables takes an AST root and returns all the interpolated
|
||||||
// variables that are detected in the AST tree.
|
// variables that are detected in the AST tree.
|
||||||
func DetectVariables(root ast.Node) ([]InterpolatedVariable, error) {
|
func DetectVariables(root ast.Node) ([]InterpolatedVariable, error) {
|
||||||
|
|
|
@ -9,10 +9,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewInterpolatedVariable(t *testing.T) {
|
func TestNewInterpolatedVariable(t *testing.T) {
|
||||||
cases := []struct {
|
tests := []struct {
|
||||||
Input string
|
Input string
|
||||||
Result InterpolatedVariable
|
Want InterpolatedVariable
|
||||||
Error bool
|
Error bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"var.foo",
|
"var.foo",
|
||||||
|
@ -22,6 +22,18 @@ func TestNewInterpolatedVariable(t *testing.T) {
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"local.foo",
|
||||||
|
&LocalVariable{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"local.foo.nope",
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"module.foo.bar",
|
"module.foo.bar",
|
||||||
&ModuleVariable{
|
&ModuleVariable{
|
||||||
|
@ -73,14 +85,19 @@ func TestNewInterpolatedVariable(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tc := range cases {
|
for i, test := range tests {
|
||||||
actual, err := NewInterpolatedVariable(tc.Input)
|
t.Run(test.Input, func(t *testing.T) {
|
||||||
if err != nil != tc.Error {
|
got, err := NewInterpolatedVariable(test.Input)
|
||||||
t.Fatalf("%d. Error: %s", i, err)
|
if err != nil != test.Error {
|
||||||
}
|
t.Errorf("%d. Error: %s", i, err)
|
||||||
if !reflect.DeepEqual(actual, tc.Result) {
|
}
|
||||||
t.Fatalf("%d bad: %#v", i, actual)
|
if !test.Error && !reflect.DeepEqual(got, test.Want) {
|
||||||
}
|
t.Errorf(
|
||||||
|
"wrong result\ninput: %s\ngot: %#v\nwant: %#v",
|
||||||
|
test.Input, got, test.Want,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue