Skip to content

Commit

Permalink
tflint: Remove duplicate variable references (#1072)
Browse files Browse the repository at this point in the history
  • Loading branch information
wata727 committed Mar 6, 2021
1 parent 5e028e7 commit 056ce5c
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 4 deletions.
6 changes: 3 additions & 3 deletions tflint/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,17 +370,17 @@ func prepareVariableValues(config *configs.Config, variables ...terraform.InputV
return variableValues
}

func listVarRefs(expr hcl.Expression) []addrs.InputVariable {
func listVarRefs(expr hcl.Expression) map[string]addrs.InputVariable {
refs, diags := lang.ReferencesInExpr(expr)
if diags.HasErrors() {
// Maybe this is bug
panic(diags.Err())
}

ret := []addrs.InputVariable{}
ret := map[string]addrs.InputVariable{}
for _, ref := range refs {
if varRef, ok := ref.Subject.(addrs.InputVariable); ok {
ret = append(ret, varRef)
ret[varRef.String()] = varRef
}
}

Expand Down
64 changes: 63 additions & 1 deletion tflint/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts"
hcl "github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/hashicorp/terraform/addrs"
"github.com/hashicorp/terraform/configs"
"github.com/zclconf/go-cty/cty"
)
Expand Down Expand Up @@ -206,7 +207,10 @@ func Test_NewModuleRunners_modVars(t *testing.T) {
},
},
}
opts = []cmp.Option{cmpopts.IgnoreFields(hcl.Pos{}, "Byte")}
opts = []cmp.Option{
cmpopts.IgnoreFields(hcl.Pos{}, "Byte"),
cmpopts.SortSlices(func(x, y *moduleVariable) bool { return x.DeclRange.Start.Line > y.DeclRange.Start.Line }),
}
if !cmp.Equal(expected, grandchild.modVars, opts...) {
t.Fatalf("`%s` module variables are unmatched: Diff=%s", grandchild.TFConfig.Path.String(), cmp.Diff(expected, grandchild.modVars, opts...))
}
Expand Down Expand Up @@ -645,3 +649,61 @@ func Test_DecodeRuleConfig_emptyBody(t *testing.T) {
t.Fatalf("Expected error message is %s, but got %s", expected, err.Error())
}
}

func Test_listVarRefs(t *testing.T) {
cases := []struct {
Name string
Expr string
Expected map[string]addrs.InputVariable
}{
{
Name: "literal",
Expr: "1",
Expected: map[string]addrs.InputVariable{},
},
{
Name: "input variable",
Expr: "var.foo",
Expected: map[string]addrs.InputVariable{
"var.foo": {Name: "foo"},
},
},
{
Name: "local variable",
Expr: "local.bar",
Expected: map[string]addrs.InputVariable{},
},
{
Name: "multiple input variables",
Expr: `format("Hello, %s %s!", var.first_name, var.last_name)`,
Expected: map[string]addrs.InputVariable{
"var.first_name": {Name: "first_name"},
"var.last_name": {Name: "last_name"},
},
},
{
Name: "map input variable",
Expr: `{
name = var.tags["name"]
env = var.tags["env"]
}`,
Expected: map[string]addrs.InputVariable{
"var.tags": {Name: "tags"},
},
},
}

for _, tc := range cases {
expr, diags := hclsyntax.ParseExpression([]byte(tc.Expr), "template.tf", hcl.InitialPos)
if diags.HasErrors() {
t.Fatal(diags)
}

refs := listVarRefs(expr)

opt := cmpopts.IgnoreUnexported(addrs.InputVariable{})
if !cmp.Equal(tc.Expected, refs, opt) {
t.Fatalf("%s: Diff=%s", tc.Name, cmp.Diff(tc.Expected, refs, opt))
}
}
}

0 comments on commit 056ce5c

Please sign in to comment.