Skip to content

Commit 76d394e

Browse files
authored
Supporting heredoc (#17)
Signed-off-by: Lasse Gaardsholt <[email protected]>
1 parent 980de31 commit 76d394e

File tree

2 files changed

+76
-15
lines changed

2 files changed

+76
-15
lines changed

rules/terraform_lists_trailing_comma.go

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,25 +60,51 @@ func (r *TerraformListsTrailingCommaRule) Check(runner tflint.Runner) error {
6060
return nil
6161
}
6262

63-
if lastItemRange.End.Byte < len(file.Bytes) && file.Bytes[lastItemRange.End.Byte] != ',' {
64-
if err := runner.EmitIssueWithFix(
65-
r,
66-
"Last item in lists should always end with a trailing comma",
67-
listRange,
68-
func(f tflint.Fixer) error {
69-
return f.InsertTextAfter(lastItemRange, ",")
70-
},
71-
); err != nil {
72-
return hcl.Diagnostics{
73-
{
74-
Severity: hcl.DiagError,
75-
Summary: "failed to call EmitIssueWithFix()",
76-
Detail: err.Error(),
77-
},
63+
// Check if there's already a trailing comma after the last item
64+
// We need to skip whitespace and newlines to handle heredoc cases
65+
commaPos := lastItemRange.End.Byte
66+
67+
// Skip whitespace and newlines after the last item to look for a comma
68+
for commaPos < len(file.Bytes) && (file.Bytes[commaPos] == ' ' || file.Bytes[commaPos] == '\t' || file.Bytes[commaPos] == '\n' || file.Bytes[commaPos] == '\r') {
69+
commaPos++
70+
}
71+
72+
if commaPos < len(file.Bytes) && file.Bytes[commaPos] == ',' {
73+
// It already has a trailling comma
74+
return nil
75+
}
76+
77+
insertText := ","
78+
// Check if the last item is a heredoc.
79+
// A heredoc is a TemplateExpr with a single LiteralValueExpr part.
80+
if template, ok := lastItem.(*hclsyntax.TemplateExpr); ok {
81+
if len(template.Parts) == 1 {
82+
if _, isLiteral := template.Parts[0].(*hclsyntax.LiteralValueExpr); isLiteral {
83+
// This is a strong indicator of a heredoc, especially if it spans multiple lines.
84+
if template.Range().Start.Line != template.Range().End.Line {
85+
insertText = "\n,"
86+
}
7887
}
7988
}
8089
}
8190

91+
if err := runner.EmitIssueWithFix(
92+
r,
93+
"Last item in lists should always end with a trailing comma",
94+
listRange,
95+
func(f tflint.Fixer) error {
96+
return f.InsertTextAfter(lastItemRange, insertText)
97+
},
98+
); err != nil {
99+
return hcl.Diagnostics{
100+
{
101+
Severity: hcl.DiagError,
102+
Summary: "failed to call EmitIssueWithFix()",
103+
Detail: err.Error(),
104+
},
105+
}
106+
}
107+
82108
return nil
83109
}))
84110

rules/terraform_lists_trailing_comma_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,41 @@ func Test_TerraformListsTrailingCommaRule(t *testing.T) {
3232
},
3333
},
3434
},
35+
{
36+
Name: "heredoc without trailing comma",
37+
Content: `resource "terraform_data" "test" {
38+
input = [
39+
"test",
40+
<<-HERE
41+
Lorem ipsum
42+
HERE
43+
]
44+
}`,
45+
Expected: helper.Issues{
46+
{
47+
Rule: NewTerraformListsTrailingCommaRule(),
48+
Message: "Last item in lists should always end with a trailing comma",
49+
Range: hcl.Range{
50+
Filename: "resource.tf",
51+
Start: hcl.Pos{Line: 2, Column: 11},
52+
End: hcl.Pos{Line: 7, Column: 4},
53+
},
54+
},
55+
},
56+
},
57+
{
58+
Name: "heredoc with trailing comma",
59+
Content: `resource "terraform_data" "test" {
60+
input = [
61+
"test",
62+
<<-HERE
63+
Lorem ipsum
64+
HERE
65+
,
66+
]
67+
}`,
68+
Expected: helper.Issues{},
69+
},
3570
}
3671

3772
rule := NewTerraformListsTrailingCommaRule()

0 commit comments

Comments
 (0)