Skip to content

Commit

Permalink
Add support for the bool type as a target value (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
wata727 authored Mar 26, 2023
1 parent 0dc8880 commit 9fd4538
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 3 deletions.
6 changes: 6 additions & 0 deletions helper/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,20 @@ func (r *Runner) evaluateExpr(expr hcl.Expression, target interface{}, opts *tfl
ty = cty.String
case *int:
ty = cty.Number
case *bool:
ty = cty.Bool
case *[]string:
ty = cty.List(cty.String)
case *[]int:
ty = cty.List(cty.Number)
case *[]bool:
ty = cty.List(cty.Bool)
case *map[string]string:
ty = cty.Map(cty.String)
case *map[string]int:
ty = cty.Map(cty.Number)
case *map[string]bool:
ty = cty.Map(cty.Bool)
case *cty.Value:
ty = cty.DynamicPseudoType
default:
Expand Down
6 changes: 6 additions & 0 deletions plugin/plugin2host/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,20 @@ func (c *GRPCClient) evaluateExpr(expr hcl.Expression, target interface{}, opts
ty = cty.String
case *int:
ty = cty.Number
case *bool:
ty = cty.Bool
case *[]string:
ty = cty.List(cty.String)
case *[]int:
ty = cty.List(cty.Number)
case *[]bool:
ty = cty.List(cty.Bool)
case *map[string]string:
ty = cty.Map(cty.String)
case *map[string]int:
ty = cty.Map(cty.Number)
case *map[string]bool:
ty = cty.Map(cty.Bool)
case *cty.Value:
ty = cty.DynamicPseudoType
default:
Expand Down
105 changes: 105 additions & 0 deletions plugin/plugin2host/plugin2host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,26 @@ func TestEvaluateExpr(t *testing.T) {
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "bool variable",
Expr: hclExpr(`var.foo`),
TargetType: reflect.TypeOf(true),
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
if *opts.WantType != cty.Bool {
return cty.Value{}, errors.New("wantType should be bool")
}
return evalExpr(expr, &hcl.EvalContext{
Variables: map[string]cty.Value{
"var": cty.MapVal(map[string]cty.Value{
"foo": cty.BoolVal(true),
}),
},
})
},
Want: true,
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "string list variable",
Expr: hclExpr(`var.foo`),
Expand Down Expand Up @@ -1514,6 +1534,26 @@ func TestEvaluateExpr(t *testing.T) {
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "bool list variable",
Expr: hclExpr(`var.foo`),
TargetType: reflect.TypeOf([]bool{}),
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
if *opts.WantType != cty.List(cty.Bool) {
return cty.Value{}, errors.New("wantType should be bool list")
}
return evalExpr(expr, &hcl.EvalContext{
Variables: map[string]cty.Value{
"var": cty.MapVal(map[string]cty.Value{
"foo": cty.ListVal([]cty.Value{cty.BoolVal(true), cty.BoolVal(false)}),
}),
},
})
},
Want: []bool{true, false},
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "string map variable",
Expr: hclExpr(`var.foo`),
Expand Down Expand Up @@ -1554,6 +1594,26 @@ func TestEvaluateExpr(t *testing.T) {
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "bool map variable",
Expr: hclExpr(`var.foo`),
TargetType: reflect.TypeOf(map[string]bool{}),
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
if *opts.WantType != cty.Map(cty.Bool) {
return cty.Value{}, errors.New("wantType should be bool map")
}
return evalExpr(expr, &hcl.EvalContext{
Variables: map[string]cty.Value{
"var": cty.MapVal(map[string]cty.Value{
"foo": cty.MapVal(map[string]cty.Value{"foo": cty.BoolVal(true), "bar": cty.BoolVal(false)}),
}),
},
})
},
Want: map[string]bool{"foo": true, "bar": false},
GetFileImpl: fileExists,
ErrCheck: neverHappend,
},
{
Name: "object variable",
Expr: hclExpr(`var.foo`),
Expand Down Expand Up @@ -2046,6 +2106,20 @@ func TestEvaluateExpr_callback(t *testing.T) {
return err == nil || err.Error() != "value is 1"
},
},
{
name: "callback with bool",
expr: hclExpr(`true`),
target: func(val bool) error {
return fmt.Errorf("value is %t", val)
},
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return cty.BoolVal(true), nil
},
getFileImpl: fileExists,
errCheck: func(err error) bool {
return err == nil || err.Error() != "value is true"
},
},
{
name: "callback with []string",
expr: hclExpr(`["foo", "bar"]`),
Expand Down Expand Up @@ -2074,6 +2148,20 @@ func TestEvaluateExpr_callback(t *testing.T) {
return err == nil || err.Error() != `value is []int{1, 2}`
},
},
{
name: "callback with []bool",
expr: hclExpr(`[true, false]`),
target: func(val []bool) error {
return fmt.Errorf("value is %#v", val)
},
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return cty.ListVal([]cty.Value{cty.BoolVal(true), cty.BoolVal(false)}), nil
},
getFileImpl: fileExists,
errCheck: func(err error) bool {
return err == nil || err.Error() != `value is []bool{true, false}`
},
},
{
name: "callback with map[string]string",
expr: hclExpr(`{ "foo" = "bar", "baz" = "qux" }`),
Expand Down Expand Up @@ -2108,6 +2196,23 @@ func TestEvaluateExpr_callback(t *testing.T) {
return err == nil || err.Error() != `foo is 1, baz is 2`
},
},
{
name: "callback with map[string]bool",
expr: hclExpr(`{ "foo" = true, "baz" = false }`),
target: func(val map[string]bool) error {
return fmt.Errorf("foo is %t, baz is %t", val["foo"], val["baz"])
},
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
return cty.MapVal(map[string]cty.Value{
"foo": cty.BoolVal(true),
"baz": cty.BoolVal(false),
}), nil
},
getFileImpl: fileExists,
errCheck: func(err error) bool {
return err == nil || err.Error() != `foo is true, baz is false`
},
},
{
name: "callback with cty.Value",
expr: hclExpr(`var.foo`),
Expand Down
7 changes: 4 additions & 3 deletions tflint/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,10 @@ type Runner interface {
//
// However, if the target is cty.Value, these errors will not be returned.
//
// Here are the types that can be passed as the target: string, int, []string, []int,
// map[string]string, map[string]int, and cty.Value. Passing any other type will
// result in a panic, but you can make an exception by passing wantType as an option.
// Here are the types that can be passed as the target: string, int, bool, []string,
// []int, []bool, map[string]string, map[string]int, map[string]bool, and cty.Value.
// Passing any other type will result in a panic, but you can make an exception by
// passing wantType as an option.
//
// ```
// type complexVal struct {
Expand Down

0 comments on commit 9fd4538

Please sign in to comment.