Skip to content

Commit 07af688

Browse files
authored
deprecated_index: reject legacy splat expressions (#34)
1 parent 0a731ee commit 07af688

File tree

3 files changed

+88
-30
lines changed

3 files changed

+88
-30
lines changed

docs/rules/terraform_deprecated_index.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,30 @@ Warning: List items should be accessed using square brackets (terraform_deprecat
2525
Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_deprecated_index.md
2626
```
2727

28+
```hcl
29+
locals {
30+
list = [{a = "b}, {a = "c"}]
31+
value = list.*.a
32+
}
33+
```
34+
35+
```
36+
$ tflint
37+
1 issue(s) found:
38+
39+
Warning: List items should be accessed using square brackets (terraform_deprecated_index)
40+
41+
on example.tf line 3:
42+
3: value = list.*.a
43+
44+
Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_deprecated_index.md
45+
```
46+
2847
## Why
2948

30-
Terraform v0.12 supports traditional square brackets for accessing list items by index. However, for backward compatability with v0.11, Terraform continues to support accessing list items with the dot syntax normally used for attributes. While Terraform does not print warnings for this syntax, it is no longer documented and its use is discouraged.
49+
Terraform v0.12 supports traditional square brackets for accessing list items by index or using the splat operator (`*`). However, for backward compatibility with v0.11, Terraform continues to support accessing list items with the dot syntax normally used for attributes. While Terraform does not print warnings for this syntax, it is no longer documented and its use is discouraged.
50+
51+
* [Legacy Splat Expressions](https://developer.hashicorp.com/terraform/language/expressions/splat#legacy-attribute-only-splat-expressions)
3152

3253
## How To Fix
3354

rules/terraform_deprecated_index.go

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -49,39 +49,49 @@ func (r *TerraformDeprecatedIndexRule) Check(runner tflint.Runner) error {
4949
}
5050

5151
diags := runner.WalkExpressions(tflint.ExprWalkFunc(func(expr hcl.Expression) hcl.Diagnostics {
52+
filename := expr.Range().Filename
53+
file, err := runner.GetFile(filename)
54+
if err != nil {
55+
return hcl.Diagnostics{
56+
{
57+
Severity: hcl.DiagError,
58+
Summary: "failed to call GetFile()",
59+
Detail: err.Error(),
60+
},
61+
}
62+
}
63+
5264
for _, variable := range expr.Variables() {
53-
for _, traversal := range variable.SimpleSplit().Rel {
54-
if traversal, ok := traversal.(hcl.TraverseIndex); ok {
55-
filename := traversal.SrcRange.Filename
56-
file, err := runner.GetFile(filename)
57-
if err != nil {
58-
return hcl.Diagnostics{
59-
{
60-
Severity: hcl.DiagError,
61-
Summary: "failed to call GetFile()",
62-
Detail: err.Error(),
63-
},
64-
}
65-
}
66-
bytes := traversal.SrcRange.SliceBytes(file.Bytes)
65+
bytes := expr.Range().SliceBytes(file.Bytes)
6766

68-
tokens, diags := hclsyntax.LexExpression(bytes, filename, traversal.SrcRange.Start)
69-
if diags.HasErrors() {
70-
return diags
67+
tokens, diags := hclsyntax.LexExpression(bytes, filename, variable.SourceRange().Start)
68+
if diags.HasErrors() {
69+
return diags
70+
}
71+
72+
tokens = tokens[1:]
73+
74+
for i, token := range tokens {
75+
if token.Type == hclsyntax.TokenDot {
76+
if len(tokens) == i+1 {
77+
return nil
7178
}
7279

73-
if tokens[0].Type == hclsyntax.TokenDot {
74-
if err := runner.EmitIssue(
75-
r,
76-
"List items should be accessed using square brackets",
77-
expr.Range(),
78-
); err != nil {
79-
return hcl.Diagnostics{
80-
{
81-
Severity: hcl.DiagError,
82-
Summary: "failed to call EmitIssue()",
83-
Detail: err.Error(),
84-
},
80+
next := tokens[i+1].Type
81+
if next == hclsyntax.TokenNumberLit || next == hclsyntax.TokenStar {
82+
if tokens[0].Type == hclsyntax.TokenDot {
83+
if err := runner.EmitIssue(
84+
r,
85+
"List items should be accessed using square brackets",
86+
expr.Range(),
87+
); err != nil {
88+
return hcl.Diagnostics{
89+
{
90+
Severity: hcl.DiagError,
91+
Summary: "failed to call EmitIssue()",
92+
Detail: err.Error(),
93+
},
94+
}
8595
}
8696
}
8797
}
@@ -91,6 +101,7 @@ func (r *TerraformDeprecatedIndexRule) Check(runner tflint.Runner) error {
91101

92102
return nil
93103
}))
104+
94105
if diags.HasErrors() {
95106
return diags
96107
}

rules/terraform_deprecated_index_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,32 @@ locals {
3939
},
4040
},
4141
},
42+
{
43+
Name: "deprecated dot splat index style",
44+
Content: `
45+
locals {
46+
maplist = [{a = "b"}]
47+
values = maplist.*.a
48+
}
49+
`,
50+
Expected: helper.Issues{
51+
{
52+
Rule: NewTerraformDeprecatedIndexRule(),
53+
Message: "List items should be accessed using square brackets",
54+
Range: hcl.Range{
55+
Filename: "config.tf",
56+
Start: hcl.Pos{
57+
Line: 4,
58+
Column: 12,
59+
},
60+
End: hcl.Pos{
61+
Line: 4,
62+
Column: 23,
63+
},
64+
},
65+
},
66+
},
67+
},
4268
{
4369
Name: "attribute access",
4470
Content: `

0 commit comments

Comments
 (0)