Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow calling DecodeRuleConfig without rule config #178

Merged
merged 1 commit into from
Aug 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions hclext/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ func PartialContent(body hcl.Body, schema *BodySchema) (*BodyContent, hcl.Diagno
return ret, diags
}

// IsEmpty returns whether the body content is empty
func (b *BodyContent) IsEmpty() bool {
if b == nil {
return true
}
return len(b.Attributes) == 0 && len(b.Blocks) == 0
}

// AsNative returns self as hcl.Attributes
func (as Attributes) AsNative() hcl.Attributes {
ret := hcl.Attributes{}
Expand Down
41 changes: 41 additions & 0 deletions hclext/structure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,3 +695,44 @@ func TestContent_PartialContent(t *testing.T) {
})
}
}

func Test_IsEmpty(t *testing.T) {
tests := []struct {
name string
body *BodyContent
want bool
}{
{
name: "body is not empty",
body: &BodyContent{
Attributes: Attributes{
"foo": &Attribute{Name: "foo"},
},
},
want: false,
},
{
name: "body has empty attributes and empty blocks",
body: &BodyContent{Attributes: Attributes{}, Blocks: Blocks{}},
want: true,
},
{
name: "body has nil attributes and nil blocks",
body: &BodyContent{},
want: true,
},
{
name: "body is nil",
body: nil,
want: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if test.body.IsEmpty() != test.want {
t.Errorf("%t is expected, but got %t", test.want, test.body.IsEmpty())
}
})
}
}
2 changes: 1 addition & 1 deletion helper/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (r *Runner) DecodeRuleConfig(name string, ret interface{}) error {
}
}

return fmt.Errorf("rule `%s` not found", name)
return nil
}

// EvaluateExpr returns a value of the passed expression.
Expand Down
40 changes: 40 additions & 0 deletions helper/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,46 @@ func Test_GetModuleContent_json(t *testing.T) {
}
}

func Test_DecodeRuleConfig(t *testing.T) {
files := map[string]string{
".tflint.hcl": `
rule "test" {
enabled = true
foo = "bar"
}`,
}

runner := TestRunner(t, files)

type ruleConfig struct {
Foo string `hclext:"foo"`
}
target := &ruleConfig{}
if err := runner.DecodeRuleConfig("test", target); err != nil {
t.Fatal(err)
}

if target.Foo != "bar" {
t.Errorf("target.Foo should be `bar`, but got `%s`", target.Foo)
}
}

func Test_DecodeRuleConfig_config_not_found(t *testing.T) {
runner := TestRunner(t, map[string]string{})

type ruleConfig struct {
Foo string `hclext:"foo"`
}
target := &ruleConfig{}
if err := runner.DecodeRuleConfig("test", target); err != nil {
t.Fatal(err)
}

if target.Foo != "" {
t.Errorf("target.Foo should be empty, but got `%s`", target.Foo)
}
}

func Test_EvaluateExpr(t *testing.T) {
tests := []struct {
Name string
Expand Down
4 changes: 4 additions & 0 deletions plugin/plugin2host/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ func (c *GRPCClient) DecodeRuleConfig(name string, ret interface{}) error {
if diags.HasErrors() {
return diags
}
if content.IsEmpty() {
return nil
}

diags = hclext.DecodeBody(content, nil, ret)
if diags.HasErrors() {
return diags
Expand Down
10 changes: 10 additions & 0 deletions plugin/plugin2host/plugin2host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,16 @@ rule "test_rule" {
ServerImpl: func(name string, schema *hclext.BodySchema) (*hclext.BodyContent, map[string][]byte, error) {
return &hclext.BodyContent{}, nil, nil
},
Want: &ruleConfig{},
ErrCheck: neverHappend,
},
{
Name: "config not found with non-empty config",
RuleName: "not_found",
Target: &ruleConfig{},
ServerImpl: func(name string, schema *hclext.BodySchema) (*hclext.BodyContent, map[string][]byte, error) {
return &hclext.BodyContent{Attributes: hclext.Attributes{"foo": &hclext.Attribute{}}}, nil, nil
},
Want: &ruleConfig{},
ErrCheck: func(err error) bool {
return err == nil || err.Error() != "config file not found"
Expand Down
2 changes: 1 addition & 1 deletion plugin/plugin2host/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (s *GRPCServer) GetRuleConfigContent(ctx context.Context, req *proto.GetRul
if body == nil {
return nil, status.Error(codes.FailedPrecondition, "response body is empty")
}
if len(sources) == 0 {
if len(sources) == 0 && !body.IsEmpty() {
return nil, status.Error(codes.NotFound, "config file not found")
}

Expand Down