Skip to content

Commit 9fd4538

Browse files
authored
Add support for the bool type as a target value (#248)
1 parent 0dc8880 commit 9fd4538

File tree

4 files changed

+121
-3
lines changed

4 files changed

+121
-3
lines changed

helper/runner.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,14 +260,20 @@ func (r *Runner) evaluateExpr(expr hcl.Expression, target interface{}, opts *tfl
260260
ty = cty.String
261261
case *int:
262262
ty = cty.Number
263+
case *bool:
264+
ty = cty.Bool
263265
case *[]string:
264266
ty = cty.List(cty.String)
265267
case *[]int:
266268
ty = cty.List(cty.Number)
269+
case *[]bool:
270+
ty = cty.List(cty.Bool)
267271
case *map[string]string:
268272
ty = cty.Map(cty.String)
269273
case *map[string]int:
270274
ty = cty.Map(cty.Number)
275+
case *map[string]bool:
276+
ty = cty.Map(cty.Bool)
271277
case *cty.Value:
272278
ty = cty.DynamicPseudoType
273279
default:

plugin/plugin2host/client.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,14 +338,20 @@ func (c *GRPCClient) evaluateExpr(expr hcl.Expression, target interface{}, opts
338338
ty = cty.String
339339
case *int:
340340
ty = cty.Number
341+
case *bool:
342+
ty = cty.Bool
341343
case *[]string:
342344
ty = cty.List(cty.String)
343345
case *[]int:
344346
ty = cty.List(cty.Number)
347+
case *[]bool:
348+
ty = cty.List(cty.Bool)
345349
case *map[string]string:
346350
ty = cty.Map(cty.String)
347351
case *map[string]int:
348352
ty = cty.Map(cty.Number)
353+
case *map[string]bool:
354+
ty = cty.Map(cty.Bool)
349355
case *cty.Value:
350356
ty = cty.DynamicPseudoType
351357
default:

plugin/plugin2host/plugin2host_test.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,26 @@ func TestEvaluateExpr(t *testing.T) {
14741474
GetFileImpl: fileExists,
14751475
ErrCheck: neverHappend,
14761476
},
1477+
{
1478+
Name: "bool variable",
1479+
Expr: hclExpr(`var.foo`),
1480+
TargetType: reflect.TypeOf(true),
1481+
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
1482+
if *opts.WantType != cty.Bool {
1483+
return cty.Value{}, errors.New("wantType should be bool")
1484+
}
1485+
return evalExpr(expr, &hcl.EvalContext{
1486+
Variables: map[string]cty.Value{
1487+
"var": cty.MapVal(map[string]cty.Value{
1488+
"foo": cty.BoolVal(true),
1489+
}),
1490+
},
1491+
})
1492+
},
1493+
Want: true,
1494+
GetFileImpl: fileExists,
1495+
ErrCheck: neverHappend,
1496+
},
14771497
{
14781498
Name: "string list variable",
14791499
Expr: hclExpr(`var.foo`),
@@ -1514,6 +1534,26 @@ func TestEvaluateExpr(t *testing.T) {
15141534
GetFileImpl: fileExists,
15151535
ErrCheck: neverHappend,
15161536
},
1537+
{
1538+
Name: "bool list variable",
1539+
Expr: hclExpr(`var.foo`),
1540+
TargetType: reflect.TypeOf([]bool{}),
1541+
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
1542+
if *opts.WantType != cty.List(cty.Bool) {
1543+
return cty.Value{}, errors.New("wantType should be bool list")
1544+
}
1545+
return evalExpr(expr, &hcl.EvalContext{
1546+
Variables: map[string]cty.Value{
1547+
"var": cty.MapVal(map[string]cty.Value{
1548+
"foo": cty.ListVal([]cty.Value{cty.BoolVal(true), cty.BoolVal(false)}),
1549+
}),
1550+
},
1551+
})
1552+
},
1553+
Want: []bool{true, false},
1554+
GetFileImpl: fileExists,
1555+
ErrCheck: neverHappend,
1556+
},
15171557
{
15181558
Name: "string map variable",
15191559
Expr: hclExpr(`var.foo`),
@@ -1554,6 +1594,26 @@ func TestEvaluateExpr(t *testing.T) {
15541594
GetFileImpl: fileExists,
15551595
ErrCheck: neverHappend,
15561596
},
1597+
{
1598+
Name: "bool map variable",
1599+
Expr: hclExpr(`var.foo`),
1600+
TargetType: reflect.TypeOf(map[string]bool{}),
1601+
ServerImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
1602+
if *opts.WantType != cty.Map(cty.Bool) {
1603+
return cty.Value{}, errors.New("wantType should be bool map")
1604+
}
1605+
return evalExpr(expr, &hcl.EvalContext{
1606+
Variables: map[string]cty.Value{
1607+
"var": cty.MapVal(map[string]cty.Value{
1608+
"foo": cty.MapVal(map[string]cty.Value{"foo": cty.BoolVal(true), "bar": cty.BoolVal(false)}),
1609+
}),
1610+
},
1611+
})
1612+
},
1613+
Want: map[string]bool{"foo": true, "bar": false},
1614+
GetFileImpl: fileExists,
1615+
ErrCheck: neverHappend,
1616+
},
15571617
{
15581618
Name: "object variable",
15591619
Expr: hclExpr(`var.foo`),
@@ -2046,6 +2106,20 @@ func TestEvaluateExpr_callback(t *testing.T) {
20462106
return err == nil || err.Error() != "value is 1"
20472107
},
20482108
},
2109+
{
2110+
name: "callback with bool",
2111+
expr: hclExpr(`true`),
2112+
target: func(val bool) error {
2113+
return fmt.Errorf("value is %t", val)
2114+
},
2115+
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
2116+
return cty.BoolVal(true), nil
2117+
},
2118+
getFileImpl: fileExists,
2119+
errCheck: func(err error) bool {
2120+
return err == nil || err.Error() != "value is true"
2121+
},
2122+
},
20492123
{
20502124
name: "callback with []string",
20512125
expr: hclExpr(`["foo", "bar"]`),
@@ -2074,6 +2148,20 @@ func TestEvaluateExpr_callback(t *testing.T) {
20742148
return err == nil || err.Error() != `value is []int{1, 2}`
20752149
},
20762150
},
2151+
{
2152+
name: "callback with []bool",
2153+
expr: hclExpr(`[true, false]`),
2154+
target: func(val []bool) error {
2155+
return fmt.Errorf("value is %#v", val)
2156+
},
2157+
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
2158+
return cty.ListVal([]cty.Value{cty.BoolVal(true), cty.BoolVal(false)}), nil
2159+
},
2160+
getFileImpl: fileExists,
2161+
errCheck: func(err error) bool {
2162+
return err == nil || err.Error() != `value is []bool{true, false}`
2163+
},
2164+
},
20772165
{
20782166
name: "callback with map[string]string",
20792167
expr: hclExpr(`{ "foo" = "bar", "baz" = "qux" }`),
@@ -2108,6 +2196,23 @@ func TestEvaluateExpr_callback(t *testing.T) {
21082196
return err == nil || err.Error() != `foo is 1, baz is 2`
21092197
},
21102198
},
2199+
{
2200+
name: "callback with map[string]bool",
2201+
expr: hclExpr(`{ "foo" = true, "baz" = false }`),
2202+
target: func(val map[string]bool) error {
2203+
return fmt.Errorf("foo is %t, baz is %t", val["foo"], val["baz"])
2204+
},
2205+
serverImpl: func(expr hcl.Expression, opts tflint.EvaluateExprOption) (cty.Value, error) {
2206+
return cty.MapVal(map[string]cty.Value{
2207+
"foo": cty.BoolVal(true),
2208+
"baz": cty.BoolVal(false),
2209+
}), nil
2210+
},
2211+
getFileImpl: fileExists,
2212+
errCheck: func(err error) bool {
2213+
return err == nil || err.Error() != `foo is true, baz is false`
2214+
},
2215+
},
21112216
{
21122217
name: "callback with cty.Value",
21132218
expr: hclExpr(`var.foo`),

tflint/interface.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ type Runner interface {
190190
//
191191
// However, if the target is cty.Value, these errors will not be returned.
192192
//
193-
// Here are the types that can be passed as the target: string, int, []string, []int,
194-
// map[string]string, map[string]int, and cty.Value. Passing any other type will
195-
// result in a panic, but you can make an exception by passing wantType as an option.
193+
// Here are the types that can be passed as the target: string, int, bool, []string,
194+
// []int, []bool, map[string]string, map[string]int, map[string]bool, and cty.Value.
195+
// Passing any other type will result in a panic, but you can make an exception by
196+
// passing wantType as an option.
196197
//
197198
// ```
198199
// type complexVal struct {

0 commit comments

Comments
 (0)