diff --git a/README.md b/README.md index e5470f6..eb1f473 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ plugin "terraform" { } ``` +For more configuration about the plugin, see [Plugin Configuration](docs/configuration.md). + ## Rules See [Rules](docs/rules/README.md). diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..83ffa11 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,21 @@ +# Configuration + +This plugin can take advantage of additional features by configuring the plugin block. Currently, this configuration is only available for preset. + +Here's an example: + +```hcl +plugin "terraform" { + // Plugin common attributes + + preset = "recommended" +} +``` + +## `preset` + +Default: `all` (`recommended` for the bundled plugin) + +Enable multiple rules at once. Please see [Rules](rules/README.md) for details. Possible values are `recommended` and `all`. + +When using the bundled plugin built into TFLint, you can use this plugin without declaring a "plugin" block. In this case the default is `recommeneded`. diff --git a/docs/rules/README.md b/docs/rules/README.md index 2763285..37d46fb 100644 --- a/docs/rules/README.md +++ b/docs/rules/README.md @@ -1,24 +1,24 @@ # Rules -Terraform language rules implement recommendations from the [Terraform language documentation](https://www.terraform.io/language). If you want to enforce additional usage and style conventions in your configuration, you can author your own ruleset plugin. +Terraform Language rules implement recommendations from the [Terraform Language documentation](https://www.terraform.io/language). -Below is a list of available rules. +All rules are enabled by default, but by setting `preset = "recommended"`, you can enable only the rules marked "Recommended" among the following rules. See [Configuration](../configuration.md) for details. -|Rule|Description|Enabled| +|Rule|Description|Recommended| | --- | --- | --- | |[terraform_comment_syntax](terraform_comment_syntax.md)|Disallow `//` comments in favor of `#`|| -|[terraform_deprecated_index](terraform_deprecated_index.md)|Disallow legacy dot index syntax|| +|[terraform_deprecated_index](terraform_deprecated_index.md)|Disallow legacy dot index syntax|✔| |[terraform_deprecated_interpolation](terraform_deprecated_interpolation.md)|Disallow deprecated (0.11-style) interpolation|✔| |[terraform_documented_outputs](terraform_documented_outputs.md)|Disallow `output` declarations without description|| |[terraform_documented_variables](terraform_documented_variables.md)|Disallow `variable` declarations without description|| -|[terraform_empty_list_equality](terraform_empty_list_equality.md)|Disallow comparisons with `[]` when checking if a collection is empty|| +|[terraform_empty_list_equality](terraform_empty_list_equality.md)|Disallow comparisons with `[]` when checking if a collection is empty|✔| |[terraform_module_pinned_source](terraform_module_pinned_source.md)|Disallow specifying a git or mercurial repository as a module source without pinning to a version|✔| |[terraform_module_version](terraform_module_version.md)|Checks that Terraform modules sourced from a registry specify a version|✔| |[terraform_naming_convention](terraform_naming_convention.md)|Enforces naming conventions for resources, data sources, etc|| -|[terraform_required_providers](terraform_required_providers.md)|Require that all providers have version constraints through required_providers|| -|[terraform_required_version](terraform_required_version.md)|Disallow `terraform` declarations without require_version|| +|[terraform_required_providers](terraform_required_providers.md)|Require that all providers have version constraints through required_providers|✔| +|[terraform_required_version](terraform_required_version.md)|Disallow `terraform` declarations without require_version|✔| |[terraform_standard_module_structure](terraform_standard_module_structure.md)|Ensure that a module complies with the Terraform Standard Module Structure|| -|[terraform_typed_variables](terraform_typed_variables.md)|Disallow `variable` declarations without type|| -|[terraform_unused_declarations](terraform_unused_declarations.md)|Disallow variables, data sources, and locals that are declared but never used|| +|[terraform_typed_variables](terraform_typed_variables.md)|Disallow `variable` declarations without type|✔| +|[terraform_unused_declarations](terraform_unused_declarations.md)|Disallow variables, data sources, and locals that are declared but never used|✔| |[terraform_unused_required_providers](terraform_unused_required_providers.md)|Check that all `required_providers` are used in the module|| |[terraform_workspace_remote](terraform_workspace_remote.md)|`terraform.workspace` should not be used with a "remote" backend with remote execution|✔| diff --git a/docs/rules/terraform_deprecated_index.md b/docs/rules/terraform_deprecated_index.md index 4f56245..e798de6 100644 --- a/docs/rules/terraform_deprecated_index.md +++ b/docs/rules/terraform_deprecated_index.md @@ -2,6 +2,8 @@ Disallow legacy dot index syntax. +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/docs/rules/terraform_deprecated_interpolation.md b/docs/rules/terraform_deprecated_interpolation.md index 0a3967a..1657dc2 100644 --- a/docs/rules/terraform_deprecated_interpolation.md +++ b/docs/rules/terraform_deprecated_interpolation.md @@ -2,6 +2,8 @@ Disallow deprecated (0.11-style) interpolation +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/docs/rules/terraform_empty_list_equality.md b/docs/rules/terraform_empty_list_equality.md index 2671a71..96be19d 100644 --- a/docs/rules/terraform_empty_list_equality.md +++ b/docs/rules/terraform_empty_list_equality.md @@ -2,6 +2,8 @@ Disallow comparisons with `[]` when checking if a collection is empty. +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/docs/rules/terraform_module_pinned_source.md b/docs/rules/terraform_module_pinned_source.md index 59241e3..e2aa109 100644 --- a/docs/rules/terraform_module_pinned_source.md +++ b/docs/rules/terraform_module_pinned_source.md @@ -2,6 +2,8 @@ Disallow specifying a git or mercurial repository as a module source without pinning to a version. +> This rule is enabled by "recommended" preset. + ## Configuration Name | Default | Value diff --git a/docs/rules/terraform_module_version.md b/docs/rules/terraform_module_version.md index f6f2d4d..ff6c332 100644 --- a/docs/rules/terraform_module_version.md +++ b/docs/rules/terraform_module_version.md @@ -2,6 +2,8 @@ Ensure that all modules sourced from a [Terraform Registry](https://www.terraform.io/docs/language/modules/sources.html#terraform-registry) specify a `version`. +> This rule is enabled by "recommended" preset. + ## Configuration Name | Description | Default | Type diff --git a/docs/rules/terraform_required_providers.md b/docs/rules/terraform_required_providers.md index b140c47..b09d996 100644 --- a/docs/rules/terraform_required_providers.md +++ b/docs/rules/terraform_required_providers.md @@ -2,6 +2,8 @@ Require that all providers have version constraints through `required_providers`. +> This rule is enabled by "recommended" preset. + ## Configuration ```hcl diff --git a/docs/rules/terraform_required_version.md b/docs/rules/terraform_required_version.md index a3c88b0..4918bbd 100644 --- a/docs/rules/terraform_required_version.md +++ b/docs/rules/terraform_required_version.md @@ -2,6 +2,8 @@ Disallow `terraform` declarations without `required_version`. +> This rule is enabled by "recommended" preset. + ## Configuration ```hcl diff --git a/docs/rules/terraform_typed_variables.md b/docs/rules/terraform_typed_variables.md index 23715a6..95bed83 100644 --- a/docs/rules/terraform_typed_variables.md +++ b/docs/rules/terraform_typed_variables.md @@ -2,6 +2,8 @@ Disallow `variable` declarations without type. +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/docs/rules/terraform_unused_declarations.md b/docs/rules/terraform_unused_declarations.md index 102e186..a5e2644 100644 --- a/docs/rules/terraform_unused_declarations.md +++ b/docs/rules/terraform_unused_declarations.md @@ -2,6 +2,8 @@ Disallow variables, data sources, and locals that are declared but never used. +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/docs/rules/terraform_workspace_remote.md b/docs/rules/terraform_workspace_remote.md index bfaad4c..90b84db 100644 --- a/docs/rules/terraform_workspace_remote.md +++ b/docs/rules/terraform_workspace_remote.md @@ -10,6 +10,8 @@ rule "terraform_workspace_remote" { } ``` +> This rule is enabled by "recommended" preset. + ## Example ```hcl diff --git a/main.go b/main.go index 7a6b3b9..c2ff729 100644 --- a/main.go +++ b/main.go @@ -4,30 +4,47 @@ import ( "github.com/terraform-linters/tflint-plugin-sdk/plugin" "github.com/terraform-linters/tflint-plugin-sdk/tflint" "github.com/terraform-linters/tflint-ruleset-terraform/rules" + "github.com/terraform-linters/tflint-ruleset-terraform/terraform" ) func main() { plugin.Serve(&plugin.ServeOpts{ - RuleSet: &tflint.BuiltinRuleSet{ - Name: "terraform", - Version: "0.1.0", - Rules: []tflint.Rule{ - rules.NewTerraformCommentSyntaxRule(), - rules.NewTerraformDeprecatedIndexRule(), - rules.NewTerraformDeprecatedInterpolationRule(), - rules.NewTerraformDocumentedOutputsRule(), - rules.NewTerraformDocumentedVariablesRule(), - rules.NewTerraformEmptyListEqualityRule(), - rules.NewTerraformModulePinnedSourceRule(), - rules.NewTerraformModuleVersionRule(), - rules.NewTerraformNamingConventionRule(), - rules.NewTerraformRequiredProvidersRule(), - rules.NewTerraformRequiredVersionRule(), - rules.NewTerraformStandardModuleStructureRule(), - rules.NewTerraformTypedVariablesRule(), - rules.NewTerraformUnusedDeclarationsRule(), - rules.NewTerraformUnusedRequiredProvidersRule(), - rules.NewTerraformWorkspaceRemoteRule(), + RuleSet: &terraform.RuleSet{ + BuiltinRuleSet: tflint.BuiltinRuleSet{ + Name: "terraform", + Version: "0.1.0", + }, + PresetRules: map[string][]tflint.Rule{ + "all": { + rules.NewTerraformCommentSyntaxRule(), + rules.NewTerraformDeprecatedIndexRule(), + rules.NewTerraformDeprecatedInterpolationRule(), + rules.NewTerraformDocumentedOutputsRule(), + rules.NewTerraformDocumentedVariablesRule(), + rules.NewTerraformEmptyListEqualityRule(), + rules.NewTerraformModulePinnedSourceRule(), + rules.NewTerraformModuleVersionRule(), + rules.NewTerraformNamingConventionRule(), + rules.NewTerraformRequiredProvidersRule(), + rules.NewTerraformRequiredVersionRule(), + rules.NewTerraformStandardModuleStructureRule(), + rules.NewTerraformTypedVariablesRule(), + rules.NewTerraformUnusedDeclarationsRule(), + rules.NewTerraformUnusedRequiredProvidersRule(), + rules.NewTerraformWorkspaceRemoteRule(), + }, + "recommended": { + rules.NewTerraformDeprecatedIndexRule(), + rules.NewTerraformDeprecatedInterpolationRule(), + rules.NewTerraformEmptyListEqualityRule(), + rules.NewTerraformModulePinnedSourceRule(), + rules.NewTerraformModuleVersionRule(), + rules.NewTerraformRequiredProvidersRule(), + rules.NewTerraformRequiredVersionRule(), + rules.NewTerraformTypedVariablesRule(), + rules.NewTerraformUnusedDeclarationsRule(), + rules.NewTerraformWorkspaceRemoteRule(), + }, }, }, }) diff --git a/rules/terraform_comment_syntax.go b/rules/terraform_comment_syntax.go index a94c9b3..ff162ef 100644 --- a/rules/terraform_comment_syntax.go +++ b/rules/terraform_comment_syntax.go @@ -26,7 +26,7 @@ func (r *TerraformCommentSyntaxRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformCommentSyntaxRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_deprecated_index.go b/rules/terraform_deprecated_index.go index 8f82796..72a0fb1 100644 --- a/rules/terraform_deprecated_index.go +++ b/rules/terraform_deprecated_index.go @@ -24,7 +24,7 @@ func (r *TerraformDeprecatedIndexRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformDeprecatedIndexRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_documented_outputs.go b/rules/terraform_documented_outputs.go index 3206bd0..7d3e61f 100644 --- a/rules/terraform_documented_outputs.go +++ b/rules/terraform_documented_outputs.go @@ -26,7 +26,7 @@ func (r *TerraformDocumentedOutputsRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformDocumentedOutputsRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_documented_variables.go b/rules/terraform_documented_variables.go index 1149a05..668ef62 100644 --- a/rules/terraform_documented_variables.go +++ b/rules/terraform_documented_variables.go @@ -26,7 +26,7 @@ func (r *TerraformDocumentedVariablesRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformDocumentedVariablesRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_naming_convention.go b/rules/terraform_naming_convention.go index 35a308c..cdc2b81 100644 --- a/rules/terraform_naming_convention.go +++ b/rules/terraform_naming_convention.go @@ -61,7 +61,7 @@ func (r *TerraformNamingConventionRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformNamingConventionRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_required_providers.go b/rules/terraform_required_providers.go index f9a2f69..00b07dc 100644 --- a/rules/terraform_required_providers.go +++ b/rules/terraform_required_providers.go @@ -28,7 +28,7 @@ func (r *TerraformRequiredProvidersRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformRequiredProvidersRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_required_version.go b/rules/terraform_required_version.go index 2e5ce20..71bc6d7 100644 --- a/rules/terraform_required_version.go +++ b/rules/terraform_required_version.go @@ -24,7 +24,7 @@ func (r *TerraformRequiredVersionRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformRequiredVersionRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_standard_module_structure.go b/rules/terraform_standard_module_structure.go index e44edc4..f58365b 100644 --- a/rules/terraform_standard_module_structure.go +++ b/rules/terraform_standard_module_structure.go @@ -33,7 +33,7 @@ func (r *TerraformStandardModuleStructureRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformStandardModuleStructureRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_typed_variables.go b/rules/terraform_typed_variables.go index 2a7d90e..321853d 100644 --- a/rules/terraform_typed_variables.go +++ b/rules/terraform_typed_variables.go @@ -25,7 +25,7 @@ func (r *TerraformTypedVariablesRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformTypedVariablesRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_unused_declaration.go b/rules/terraform_unused_declaration.go index 43e5c81..c7f4fc4 100644 --- a/rules/terraform_unused_declaration.go +++ b/rules/terraform_unused_declaration.go @@ -32,7 +32,7 @@ func (r *TerraformUnusedDeclarationsRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformUnusedDeclarationsRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/rules/terraform_unused_required_providers.go b/rules/terraform_unused_required_providers.go index bfdf337..61b3711 100644 --- a/rules/terraform_unused_required_providers.go +++ b/rules/terraform_unused_required_providers.go @@ -25,7 +25,7 @@ func (r *TerraformUnusedRequiredProvidersRule) Name() string { // Enabled returns whether the rule is enabled by default func (r *TerraformUnusedRequiredProvidersRule) Enabled() bool { - return false + return true } // Severity returns the rule severity diff --git a/terraform/config.go b/terraform/config.go new file mode 100644 index 0000000..d4a23d6 --- /dev/null +++ b/terraform/config.go @@ -0,0 +1,6 @@ +package terraform + +// Config is the configuration for the ruleset. +type Config struct { + Preset string `hclext:"preset,optional"` +} diff --git a/terraform/ruleset.go b/terraform/ruleset.go new file mode 100644 index 0000000..a2fed64 --- /dev/null +++ b/terraform/ruleset.go @@ -0,0 +1,86 @@ +package terraform + +import ( + "fmt" + "strings" + + "github.com/terraform-linters/tflint-plugin-sdk/hclext" + "github.com/terraform-linters/tflint-plugin-sdk/logger" + "github.com/terraform-linters/tflint-plugin-sdk/tflint" +) + +// RuleSet is the custom ruleset for the Terraform Language. +type RuleSet struct { + tflint.BuiltinRuleSet + + PresetRules map[string][]tflint.Rule + + globalConfig *tflint.Config + rulesetConfig *Config +} + +func (r *RuleSet) ConfigSchema() *hclext.BodySchema { + r.rulesetConfig = &Config{} + return hclext.ImpliedBodySchema(r.rulesetConfig) +} + +// ApplyGlobalConfig is normally not expected to be overridden, +// but here the preset setting takes precedence over DisabledByDefault, +// so it just overrides and saves the global config to the ruleset. +func (r *RuleSet) ApplyGlobalConfig(config *tflint.Config) error { + r.globalConfig = config + return nil +} + +// ApplyConfig controls rule activation based on global and preset configs. +// The priority of rules is in the following order: +// +// 1. Rule config declared in each "rule" block +// 2. Preset config declared in "plugin" block +// 3. The `disabled_by_default` declared in global "config" block +// +// Individual rule configs always take precedence over anything else. +// Preset rules are then prioritized. For example, if `disabled_by_default = true` +// and `preset = "recommended"` is declared, all recommended rules will be enabled. +func (r *RuleSet) ApplyConfig(body *hclext.BodyContent) error { + diags := hclext.DecodeBody(body, nil, r.rulesetConfig) + if diags.HasErrors() { + return diags + } + + if r.globalConfig.DisabledByDefault { + logger.Debug("Only mode is enabled. Ignoring default plugin rules") + } + + // Default preset is "all" + rules := r.PresetRules["all"] + _, presetExists := body.Attributes["preset"] + if presetExists { + presetRules, exists := r.PresetRules[r.rulesetConfig.Preset] + if !exists { + validPresets := []string{} + for name := range r.PresetRules { + validPresets = append(validPresets, name) + } + return fmt.Errorf(`preset "%s" is not found. Valid presets are %s`, r.rulesetConfig.Preset, strings.Join(validPresets, ", ")) + } + rules = presetRules + } + + r.EnabledRules = []tflint.Rule{} + for _, rule := range rules { + enabled := rule.Enabled() + if cfg := r.globalConfig.Rules[rule.Name()]; cfg != nil { + enabled = cfg.Enabled + } else if r.globalConfig.DisabledByDefault && !presetExists { + // Preset takes precedence over DisabledByDefault + enabled = false + } + + if enabled { + r.EnabledRules = append(r.EnabledRules, rule) + } + } + + return nil +} diff --git a/terraform/ruleset_test.go b/terraform/ruleset_test.go new file mode 100644 index 0000000..6741f3c --- /dev/null +++ b/terraform/ruleset_test.go @@ -0,0 +1,181 @@ +package terraform + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclsyntax" + "github.com/terraform-linters/tflint-plugin-sdk/hclext" + "github.com/terraform-linters/tflint-plugin-sdk/tflint" + "github.com/terraform-linters/tflint-ruleset-terraform/rules" +) + +func TestApplyConfig(t *testing.T) { + mustParseExpr := func(input string) hcl.Expression { + expr, diags := hclsyntax.ParseExpression([]byte(input), "", hcl.InitialPos) + if diags.HasErrors() { + panic(diags) + } + return expr + } + + tests := []struct { + name string + global *tflint.Config + config *hclext.BodyContent + want []string + }{ + { + name: "default", + global: &tflint.Config{}, + config: &hclext.BodyContent{}, + want: []string{ + "terraform_comment_syntax", + "terraform_deprecated_index", + "terraform_deprecated_interpolation", + }, + }, + { + name: "disabled by default", + global: &tflint.Config{DisabledByDefault: true}, + config: &hclext.BodyContent{}, + want: []string{}, + }, + { + name: "preset", + global: &tflint.Config{}, + config: &hclext.BodyContent{ + Attributes: hclext.Attributes{ + "preset": &hclext.Attribute{Name: "preset", Expr: mustParseExpr(`"recommended"`)}, + }, + }, + want: []string{ + "terraform_comment_syntax", + "terraform_deprecated_index", + }, + }, + { + name: "rule config", + global: &tflint.Config{ + Rules: map[string]*tflint.RuleConfig{ + "terraform_comment_syntax": { + Name: "terraform_comment_syntax", + Enabled: false, + }, + }, + }, + config: &hclext.BodyContent{}, + want: []string{ + "terraform_deprecated_index", + "terraform_deprecated_interpolation", + }, + }, + { + name: "disabled by default + preset", + global: &tflint.Config{DisabledByDefault: true}, + config: &hclext.BodyContent{ + Attributes: hclext.Attributes{ + "preset": &hclext.Attribute{Name: "preset", Expr: mustParseExpr(`"recommended"`)}, + }, + }, + want: []string{ + "terraform_comment_syntax", + "terraform_deprecated_index", + }, + }, + { + name: "disabled by default + rule config", + global: &tflint.Config{ + Rules: map[string]*tflint.RuleConfig{ + "terraform_comment_syntax": { + Name: "terraform_comment_syntax", + Enabled: true, + }, + }, + DisabledByDefault: true, + }, + config: &hclext.BodyContent{}, + want: []string{ + "terraform_comment_syntax", + }, + }, + { + name: "preset + rule config", + global: &tflint.Config{ + Rules: map[string]*tflint.RuleConfig{ + "terraform_comment_syntax": { + Name: "terraform_comment_syntax", + Enabled: false, + }, + }, + }, + config: &hclext.BodyContent{ + Attributes: hclext.Attributes{ + "preset": &hclext.Attribute{Name: "preset", Expr: mustParseExpr(`"recommended"`)}, + }, + }, + want: []string{ + "terraform_deprecated_index", + }, + }, + { + name: "disabled by default + preset + rule config", + global: &tflint.Config{ + Rules: map[string]*tflint.RuleConfig{ + "terraform_comment_syntax": { + Name: "terraform_comment_syntax", + Enabled: false, + }, + }, + DisabledByDefault: true, + }, + config: &hclext.BodyContent{ + Attributes: hclext.Attributes{ + "preset": &hclext.Attribute{Name: "preset", Expr: mustParseExpr(`"recommended"`)}, + }, + }, + want: []string{ + "terraform_deprecated_index", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ruleset := &RuleSet{ + PresetRules: map[string][]tflint.Rule{ + "all": { + rules.NewTerraformCommentSyntaxRule(), + rules.NewTerraformDeprecatedIndexRule(), + rules.NewTerraformDeprecatedInterpolationRule(), + }, + "recommended": { + rules.NewTerraformCommentSyntaxRule(), + rules.NewTerraformDeprecatedIndexRule(), + }, + }, + rulesetConfig: &Config{}, + } + + err := ruleset.ApplyGlobalConfig(test.global) + if err != nil { + t.Fatal(err) + } + + err = ruleset.ApplyConfig(test.config) + if err != nil { + t.Fatal(err) + } + + got := make([]string, len(ruleset.EnabledRules)) + for i, r := range ruleset.EnabledRules { + got[i] = r.Name() + } + + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf(diff) + } + }) + } +}