Skip to content

Commit 346f86f

Browse files
authored
Allow ruleset to accept Only option (#198)
1 parent 6997918 commit 346f86f

File tree

8 files changed

+459
-282
lines changed

8 files changed

+459
-282
lines changed

plugin/fromproto/fromproto.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,11 @@ func Config(config *proto.ApplyGlobalConfig_Config) *tflint.Config {
180180
for name, rule := range config.Rules {
181181
rules[name] = &tflint.RuleConfig{Name: rule.Name, Enabled: rule.Enabled}
182182
}
183-
return &tflint.Config{Rules: rules, DisabledByDefault: config.DisabledByDefault}
183+
return &tflint.Config{
184+
Rules: rules,
185+
DisabledByDefault: config.DisabledByDefault,
186+
Only: config.Only,
187+
}
184188
}
185189

186190
// GetModuleContentOption converts proto.GetModuleContent_Option to tflint.GetModuleContentOption

plugin/host2plugin/host2plugin_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ func TestApplyGlobalConfig(t *testing.T) {
299299
"test2": {Name: "test2", Enabled: false},
300300
},
301301
DisabledByDefault: true,
302+
Only: []string{"test_rule1", "test_rule2"},
302303
},
303304
ServerImpl: func(config *tflint.Config) error {
304305
want := &tflint.Config{
@@ -307,6 +308,7 @@ func TestApplyGlobalConfig(t *testing.T) {
307308
"test2": {Name: "test2", Enabled: false},
308309
},
309310
DisabledByDefault: true,
311+
Only: []string{"test_rule1", "test_rule2"},
310312
}
311313

312314
if diff := cmp.Diff(config, want); diff != "" {

plugin/proto/tflint.pb.go

Lines changed: 285 additions & 276 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/proto/tflint.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ message ApplyGlobalConfig {
4545
message Config {
4646
map<string, RuleConfig> rules = 1;
4747
bool disabled_by_default = 2;
48+
repeated string only = 3;
4849
}
4950
message RuleConfig {
5051
string name = 1;

plugin/toproto/toproto.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ func Config(config *tflint.Config) *proto.ApplyGlobalConfig_Config {
138138
for name, rule := range config.Rules {
139139
rules[name] = &proto.ApplyGlobalConfig_RuleConfig{Name: rule.Name, Enabled: rule.Enabled}
140140
}
141-
return &proto.ApplyGlobalConfig_Config{Rules: rules, DisabledByDefault: config.DisabledByDefault}
141+
return &proto.ApplyGlobalConfig_Config{
142+
Rules: rules,
143+
DisabledByDefault: config.DisabledByDefault,
144+
Only: config.Only,
145+
}
142146
}
143147

144148
// GetModuleContentOption converts tflint.GetModuleContentOption to proto.GetModuleContent_Option

tflint/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package tflint
44
type Config struct {
55
Rules map[string]*RuleConfig
66
DisabledByDefault bool
7+
Only []string
78
}
89

910
// RuleConfig is a TFLint's rule configuration.

tflint/ruleset.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ package tflint
22

33
import (
44
"fmt"
5-
"log"
65

76
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
7+
"github.com/terraform-linters/tflint-plugin-sdk/logger"
88
)
99

1010
var _ RuleSet = &BuiltinRuleSet{}
@@ -42,16 +42,30 @@ func (r *BuiltinRuleSet) RuleNames() []string {
4242
// ApplyGlobalConfig applies the common config to the ruleset.
4343
// This is not supposed to be overridden from custom rulesets.
4444
// Override the ApplyConfig if you want to apply the plugin's own configuration.
45+
//
46+
// The priority of rule configs is as follows:
47+
//
48+
// 1. --only option
49+
// 2. Rule config declared in each "rule" block
50+
// 3. The `disabled_by_default` declared in global "config" block
4551
func (r *BuiltinRuleSet) ApplyGlobalConfig(config *Config) error {
4652
r.EnabledRules = []Rule{}
53+
only := map[string]bool{}
4754

48-
if config.DisabledByDefault {
49-
log.Printf("[DEBUG] Only mode is enabled. Ignoring default plugin rules")
55+
if len(config.Only) > 0 {
56+
logger.Debug("Only mode is enabled. Ignoring default plugin rules")
57+
for _, rule := range config.Only {
58+
only[rule] = true
59+
}
60+
} else if config.DisabledByDefault {
61+
logger.Debug("Default plugin rules are disabled by default")
5062
}
5163

5264
for _, rule := range r.Rules {
5365
enabled := rule.Enabled()
54-
if cfg := config.Rules[rule.Name()]; cfg != nil {
66+
if len(only) > 0 {
67+
enabled = only[rule.Name()]
68+
} else if cfg := config.Rules[rule.Name()]; cfg != nil {
5569
enabled = cfg.Enabled
5670
} else if config.DisabledByDefault {
5771
enabled = false

tflint/ruleset_test.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package tflint
2+
3+
import (
4+
"testing"
5+
6+
"github.com/google/go-cmp/cmp"
7+
)
8+
9+
type testRule struct {
10+
DefaultRule
11+
name string
12+
}
13+
14+
func (r *testRule) Name() string { return r.name }
15+
func (r *testRule) Enabled() bool { return true }
16+
func (r *testRule) Severity() Severity { return ERROR }
17+
func (r *testRule) Check(Runner) error { return nil }
18+
19+
type testRule1 struct {
20+
testRule
21+
}
22+
23+
type testRule2 struct {
24+
testRule
25+
}
26+
27+
type testRule3 struct {
28+
testRule
29+
}
30+
31+
func TestApplyGlobalConfig(t *testing.T) {
32+
tests := []struct {
33+
name string
34+
config *Config
35+
want []string
36+
}{
37+
{
38+
name: "default",
39+
config: &Config{},
40+
want: []string{"test_rule1", "test_rule2", "test_rule3"},
41+
},
42+
{
43+
name: "disabled by default",
44+
config: &Config{DisabledByDefault: true},
45+
want: []string{},
46+
},
47+
{
48+
name: "rule config",
49+
config: &Config{
50+
Rules: map[string]*RuleConfig{
51+
"test_rule1": {
52+
Name: "test_rule1",
53+
Enabled: false,
54+
},
55+
},
56+
},
57+
want: []string{"test_rule2", "test_rule3"},
58+
},
59+
{
60+
name: "only",
61+
config: &Config{Only: []string{"test_rule1"}},
62+
want: []string{"test_rule1"},
63+
},
64+
{
65+
name: "disabled by default + rule config",
66+
config: &Config{
67+
Rules: map[string]*RuleConfig{
68+
"test_rule2": {
69+
Name: "test_rule2",
70+
Enabled: true,
71+
},
72+
},
73+
DisabledByDefault: true,
74+
},
75+
want: []string{"test_rule2"},
76+
},
77+
{
78+
name: "only + rule config",
79+
config: &Config{
80+
Rules: map[string]*RuleConfig{
81+
"test_rule1": {
82+
Name: "test_rule1",
83+
Enabled: false,
84+
},
85+
},
86+
Only: []string{"test_rule1", "test_rule2"},
87+
},
88+
want: []string{"test_rule1", "test_rule2"},
89+
},
90+
{
91+
name: "disabled by default + only",
92+
config: &Config{
93+
DisabledByDefault: true,
94+
Only: []string{"test_rule1", "test_rule2"},
95+
},
96+
want: []string{"test_rule1", "test_rule2"},
97+
},
98+
{
99+
name: "disabled by default + only + rule config",
100+
config: &Config{
101+
Rules: map[string]*RuleConfig{
102+
"test_rule2": {
103+
Name: "test_rule2",
104+
Enabled: true,
105+
},
106+
"test_rule3": {
107+
Name: "test_rule3",
108+
Enabled: false,
109+
},
110+
},
111+
DisabledByDefault: true,
112+
Only: []string{"test_rule1", "test_rule3"},
113+
},
114+
want: []string{"test_rule1", "test_rule3"},
115+
},
116+
}
117+
118+
for _, test := range tests {
119+
t.Run(test.name, func(t *testing.T) {
120+
ruleset := &BuiltinRuleSet{
121+
Rules: []Rule{
122+
&testRule1{testRule: testRule{name: "test_rule1"}},
123+
&testRule2{testRule: testRule{name: "test_rule2"}},
124+
&testRule3{testRule: testRule{name: "test_rule3"}},
125+
},
126+
}
127+
128+
if err := ruleset.ApplyGlobalConfig(test.config); err != nil {
129+
t.Fatal(err)
130+
}
131+
132+
got := make([]string, len(ruleset.EnabledRules))
133+
for i, r := range ruleset.EnabledRules {
134+
got[i] = r.Name()
135+
}
136+
137+
if diff := cmp.Diff(got, test.want); diff != "" {
138+
t.Errorf(diff)
139+
}
140+
})
141+
}
142+
}

0 commit comments

Comments
 (0)