From 53b1edeb987cf84261352fb4166d9494d00b1048 Mon Sep 17 00:00:00 2001 From: Bruno Ferreira Date: Wed, 10 Aug 2022 04:09:46 +0100 Subject: [PATCH] `terraform_empty_list_equality`: improve expression detection (#1426) --- .../terraform_empty_list_equality.go | 32 +++++++--------- .../terraform_empty_list_equality_test.go | 38 +++++++++++++++++++ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/rules/terraformrules/terraform_empty_list_equality.go b/rules/terraformrules/terraform_empty_list_equality.go index 434467ada..83bbfd7a8 100644 --- a/rules/terraformrules/terraform_empty_list_equality.go +++ b/rules/terraformrules/terraform_empty_list_equality.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" "github.com/terraform-linters/tflint/tflint" + "github.com/zclconf/go-cty/cty" ) // TerraformEmptyListEqualityRule checks whether is there a comparison with an empty list @@ -52,30 +53,25 @@ func (r *TerraformEmptyListEqualityRule) Check(runner *tflint.Runner) error { return nil } +// checkEmptyList visits all blocks that can contain expressions and checks for comparisons with static empty list func (r *TerraformEmptyListEqualityRule) checkEmptyList(runner *tflint.Runner) error { return runner.WalkExpressions(func(expr hcl.Expression) error { - if conditionalExpr, ok := expr.(*hclsyntax.ConditionalExpr); ok { - if binaryOpExpr, ok := conditionalExpr.Condition.(*hclsyntax.BinaryOpExpr); ok { - if binaryOpExpr.Op.Type.FriendlyName() == "bool" { - if right, ok := binaryOpExpr.RHS.(*hclsyntax.TupleConsExpr); ok { - checkEmptyList(right, runner, r, binaryOpExpr) - } - if left, ok := binaryOpExpr.LHS.(*hclsyntax.TupleConsExpr); ok { - checkEmptyList(left, runner, r, binaryOpExpr) - } - } + if binaryOpExpr, ok := expr.(*hclsyntax.BinaryOpExpr); ok && binaryOpExpr.Op.Type == cty.Bool { + if tupleConsExpr, ok := binaryOpExpr.LHS.(*hclsyntax.TupleConsExpr); ok && len(tupleConsExpr.Exprs) == 0 { + r.emitIssue(binaryOpExpr.Range(), runner) + } else if tupleConsExpr, ok := binaryOpExpr.RHS.(*hclsyntax.TupleConsExpr); ok && len(tupleConsExpr.Exprs) == 0 { + r.emitIssue(binaryOpExpr.Range(), runner) } } return nil }) } -func checkEmptyList(tupleConsExpr *hclsyntax.TupleConsExpr, runner *tflint.Runner, r *TerraformEmptyListEqualityRule, binaryOpExpr *hclsyntax.BinaryOpExpr) { - if len(tupleConsExpr.Exprs) == 0 { - runner.EmitIssue( - r, - "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", - binaryOpExpr.Range(), - ) - } +// emitIssue emits issue for comparison with static empty list +func (r *TerraformEmptyListEqualityRule) emitIssue(exprRange hcl.Range, runner *tflint.Runner) { + runner.EmitIssue( + r, + "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", + exprRange, + ) } diff --git a/rules/terraformrules/terraform_empty_list_equality_test.go b/rules/terraformrules/terraform_empty_list_equality_test.go index a99797ef8..484fa4209 100644 --- a/rules/terraformrules/terraform_empty_list_equality_test.go +++ b/rules/terraformrules/terraform_empty_list_equality_test.go @@ -30,6 +30,16 @@ resource "aws_db_instance" "mysql" { End: hcl.Pos{Line: 3, Column: 18}, }, }, + }, + }, + { + Name: "multiple comparisons with [] are not recommended", + Content: ` +resource "aws_db_instance" "mysql" { + count = [] == [] || [] == [] ? 1 : 0 + instance_class = "m4.2xlarge" +}`, + Expected: tflint.Issues{ { Rule: NewTerraformEmptyListEqualityRule(), Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", @@ -39,6 +49,34 @@ resource "aws_db_instance" "mysql" { End: hcl.Pos{Line: 3, Column: 18}, }, }, + { + Rule: NewTerraformEmptyListEqualityRule(), + Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", + Range: hcl.Range{ + Filename: "resource.tf", + Start: hcl.Pos{Line: 3, Column: 22}, + End: hcl.Pos{Line: 3, Column: 30}, + }, + }, + }, + }, + { + Name: "comparing with [] inside parenthesis is not recommended", + Content: ` +resource "aws_db_instance" "mysql" { + count = ([] == []) ? 1 : 0 + instance_class = "m4.2xlarge" +}`, + Expected: tflint.Issues{ + { + Rule: NewTerraformEmptyListEqualityRule(), + Message: "Comparing a collection with an empty list is invalid. To detect an empty collection, check its length.", + Range: hcl.Range{ + Filename: "resource.tf", + Start: hcl.Pos{Line: 3, Column: 11}, + End: hcl.Pos{Line: 3, Column: 19}, + }, + }, }, }, {