Skip to content

Commit 7cb0f65

Browse files
authored
Make unused variable checks aware of validation blocks (#133)
1 parent 6afcb25 commit 7cb0f65

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

rules/terraform_unused_declarations.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,19 @@ func (r *TerraformUnusedDeclarationsRule) declarations(runner *terraform.Runner)
119119
{
120120
Type: "variable",
121121
LabelNames: []string{"name"},
122-
Body: &hclext.BodySchema{},
122+
Body: &hclext.BodySchema{
123+
Blocks: []hclext.BlockSchema{
124+
{
125+
Type: "validation",
126+
Body: &hclext.BodySchema{
127+
Attributes: []hclext.AttributeSchema{
128+
{Name: "condition"},
129+
{Name: "error_message"},
130+
},
131+
},
132+
},
133+
},
134+
},
123135
},
124136
{
125137
Type: "data",
@@ -150,9 +162,21 @@ func (r *TerraformUnusedDeclarationsRule) declarations(runner *terraform.Runner)
150162
}
151163

152164
func (r *TerraformUnusedDeclarationsRule) checkForRefsInExpr(expr hcl.Expression, decl *declarations) {
165+
ReferenceLoop:
153166
for _, ref := range lang.ReferencesInExpr(expr) {
154167
switch sub := ref.Subject.(type) {
155168
case addrs.InputVariable:
169+
// Input variables can refer to themselves as var.NAME inside validation blocks.
170+
// Do not mark such expressions as used, skip to next reference.
171+
if varBlock, exists := decl.Variables[sub.Name]; exists {
172+
for _, validationBlock := range varBlock.Body.Blocks {
173+
for _, attr := range validationBlock.Body.Attributes {
174+
if attr.Expr.Range().Overlaps(expr.Range()) {
175+
continue ReferenceLoop
176+
}
177+
}
178+
}
179+
}
156180
delete(decl.Variables, sub.Name)
157181
case addrs.LocalValue:
158182
delete(decl.Locals, sub.Name)

rules/terraform_unused_declarations_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,30 @@ output "d" {
179179
`,
180180
Expected: helper.Issues{},
181181
},
182+
{
183+
Name: "variable used in validation block",
184+
Content: `
185+
variable "unused" {
186+
validation {
187+
condition = var.unused != ""
188+
error_message = "variable should be empty string. got: ${var.unused}"
189+
}
190+
}
191+
`,
192+
Expected: helper.Issues{
193+
{
194+
Rule: NewTerraformUnusedDeclarationsRule(),
195+
Message: `variable "unused" is declared but not used`,
196+
Range: hcl.Range{
197+
Filename: "config.tf",
198+
Start: hcl.Pos{Line: 2, Column: 1},
199+
End: hcl.Pos{Line: 2, Column: 18},
200+
},
201+
},
202+
},
203+
Fixed: `
204+
`,
205+
},
182206
{
183207
Name: "json",
184208
JSON: true,

0 commit comments

Comments
 (0)