From ed85b79854027ecef9a541acf6c7c3c533ba30c5 Mon Sep 17 00:00:00 2001 From: cce <51567+cce@users.noreply.github.com> Date: Thu, 6 Nov 2025 07:05:40 -0500 Subject: [PATCH] feature: add enableDefaultRules config option (#1551) Co-authored-by: Oleksandr Redko --- README.md | 21 +++--- config/config.go | 19 ++--- config/config_test.go | 72 +++++++++++++++++-- config/testdata/enableAllAndDefault.toml | 4 ++ config/testdata/enableAllBut2.toml | 10 +-- config/testdata/enableAllWithRule.toml | 4 ++ config/testdata/enableDefault.toml | 3 + config/testdata/enableDefaultBut2.toml | 9 +++ config/testdata/enableDefaultPlus1.toml | 6 ++ .../enableDefaultPlusDefaultRule.toml | 6 ++ lint/config.go | 1 + 11 files changed, 122 insertions(+), 33 deletions(-) create mode 100644 config/testdata/enableAllAndDefault.toml create mode 100644 config/testdata/enableAllWithRule.toml create mode 100644 config/testdata/enableDefault.toml create mode 100644 config/testdata/enableDefaultBut2.toml create mode 100644 config/testdata/enableDefaultPlus1.toml create mode 100644 config/testdata/enableDefaultPlusDefaultRule.toml diff --git a/README.md b/README.md index 9f18dfb..6ae104c 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ If you disable them in the config file, revive will run over 6x faster than goli - [Sample Invocations](#sample-invocations) - [Comment Directives](#comment-directives) - [Configuration](#configuration) - - [Default Configuration](#default-configuration) - [Custom Configuration](#custom-configuration) - [Recommended Configuration](#recommended-configuration) - [Rule-level file excludes](#rule-level-file-excludes) @@ -360,6 +359,15 @@ severity = "error" By default `revive` will enable only the linting rules that are named in the configuration file. For example, the previous configuration file makes `revive` to enable only _cyclomatic_ and _package-comments_ linting rules. +To enable default rules you need to use: + +```toml +enableDefaultRules = true +``` + +This will enable all rules available in `golint` and use their default configuration (i.e. the way they are hardcoded in `golint`). +The default configuration of `revive` can be found at `defaults.toml`. + To enable all available rules you need to add: ```toml @@ -416,17 +424,6 @@ Arguments = [3] Arguments = ["mypackage.Error"] ``` -### Default Configuration - -The default configuration of `revive` can be found at `defaults.toml`. -This will enable all rules available in `golint` and use their default configuration (i.e. the way they are hardcoded in `golint`). - -```shell -revive -config defaults.toml github.com/mgechev/revive -``` - -This will use the configuration file `defaults.toml`, the `default` formatter, and will run linting over the `github.com/mgechev/revive` package. - ### Custom Configuration ```shell diff --git a/config/config.go b/config/config.go index ba97832..2246444 100644 --- a/config/config.go +++ b/config/config.go @@ -210,19 +210,22 @@ func normalizeConfig(config *lint.Config) { if len(config.Rules) == 0 { config.Rules = map[string]lint.RuleConfig{} } - if config.EnableAllRules { - // Add to the configuration all rules not yet present in it - for _, r := range allRules { + + addRules := func(config *lint.Config, rules []lint.Rule) { + for _, r := range rules { ruleName := r.Name() - _, alreadyInConf := config.Rules[ruleName] - if alreadyInConf { - continue + if _, ok := config.Rules[ruleName]; !ok { + config.Rules[ruleName] = lint.RuleConfig{} } - // Add the rule with an empty conf for - config.Rules[ruleName] = lint.RuleConfig{} } } + if config.EnableAllRules { + addRules(config, allRules) + } else if config.EnableDefaultRules { + addRules(config, defaultRules) + } + severity := config.Severity if severity != "" { for k, v := range config.Rules { diff --git a/config/config_test.go b/config/config_test.go index 45cd51b..93a7dcd 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -72,6 +72,39 @@ func TestGetConfig(t *testing.T) { IgnoreGeneratedHeader: true, }, }, + "config from file enableDefault": { + confPath: "enableDefault.toml", + wantConfig: lint.Config{ + Confidence: 0.8, + IgnoreGeneratedHeader: false, + EnableDefaultRules: true, + Rules: lint.RulesConfig{ + "blank-imports": {}, + "context-as-argument": {}, + "context-keys-type": {}, + "dot-imports": {}, + "empty-block": {}, + "error-naming": {}, + "error-return": {}, + "error-strings": {}, + "errorf": {}, + "exported": {}, + "increment-decrement": {}, + "indent-error-flow": {}, + "package-comments": {}, + "range": {}, + "receiver-naming": {}, + "redefines-builtin-id": {}, + "superfluous-else": {}, + "time-naming": {}, + "unexported-return": {}, + "unreachable-code": {}, + "unused-parameter": {}, + "var-declaration": {}, + "var-naming": {}, + }, + }, + }, } { t.Run(name, func(t *testing.T) { var cfgPath string @@ -96,6 +129,9 @@ func TestGetConfig(t *testing.T) { if cfg.EnableAllRules != tc.wantConfig.EnableAllRules { t.Errorf("EnableAllRules: expected %v, got %v", tc.wantConfig.EnableAllRules, cfg.EnableAllRules) } + if cfg.EnableDefaultRules != tc.wantConfig.EnableDefaultRules { + t.Errorf("EnableDefaultRules: expected %v, got %v", tc.wantConfig.EnableDefaultRules, cfg.EnableDefaultRules) + } if cfg.ErrorCode != tc.wantConfig.ErrorCode { t.Errorf("ErrorCode: expected %v, got %v", tc.wantConfig.ErrorCode, cfg.ErrorCode) } @@ -227,30 +263,54 @@ func TestGetLintingRules(t *testing.T) { wantErr string }{ "no rules": { - confPath: "testdata/noRules.toml", + confPath: "noRules.toml", wantRulesCount: 0, }, "enableAllRules without disabled rules": { - confPath: "testdata/enableAll.toml", + confPath: "enableAll.toml", wantRulesCount: len(allRules), }, "enableAllRules with 2 disabled rules": { - confPath: "testdata/enableAllBut2.toml", + confPath: "enableAllBut2.toml", wantRulesCount: len(allRules) - 2, }, + "enableDefaultRules without disabled rules": { + confPath: "enableDefault.toml", + wantRulesCount: len(defaultRules), + }, + "enableDefaultRules with 2 disabled rules": { + confPath: "enableDefaultBut2.toml", + wantRulesCount: len(defaultRules) - 2, + }, + "enableDefaultRules plus 1 non-default rule": { + confPath: "enableDefaultPlus1.toml", + wantRulesCount: len(defaultRules) + 1, + }, + "enableAllRules and enableDefaultRules both set": { + confPath: "enableAllAndDefault.toml", + wantRulesCount: len(allRules), + }, + "enableDefaultRules plus rule already in defaults": { + confPath: "enableDefaultPlusDefaultRule.toml", + wantRulesCount: len(defaultRules), + }, + "enableAllRules plus rule already in all": { + confPath: "enableAllWithRule.toml", + wantRulesCount: len(allRules), + }, "enable 2 rules": { - confPath: "testdata/enable2.toml", + confPath: "enable2.toml", wantRulesCount: 2, }, "var-naming configure error": { - confPath: "testdata/varNamingConfigureError.toml", + confPath: "varNamingConfigureError.toml", wantErr: `cannot configure rule: "var-naming": invalid argument to the var-naming rule. Expecting a allowlist of type slice with initialisms, got string`, }, } for name, tc := range tt { t.Run(name, func(t *testing.T) { - cfg, err := GetConfig(tc.confPath) + cfg, err := GetConfig(filepath.Join("testdata", tc.confPath)) if err != nil { t.Fatalf("Unexpected error while loading conf: %v", err) } diff --git a/config/testdata/enableAllAndDefault.toml b/config/testdata/enableAllAndDefault.toml new file mode 100644 index 0000000..cbe7877 --- /dev/null +++ b/config/testdata/enableAllAndDefault.toml @@ -0,0 +1,4 @@ +# Enable all rules without duplicates + +enableAllRules = true +enableDefaultRules = true diff --git a/config/testdata/enableAllBut2.toml b/config/testdata/enableAllBut2.toml index 0e450ec..9dad9b4 100644 --- a/config/testdata/enableAllBut2.toml +++ b/config/testdata/enableAllBut2.toml @@ -1,12 +1,8 @@ -ignoreGeneratedHeader = false -severity = "warning" -confidence = 0.8 -errorCode = 0 -warningCode = 0 +# Enable all rules without 1 default and 1 non-default enableAllRules = true [rule.exported] - disabled=true +Disabled = true [rule.cyclomatic] - disabled=true +Disabled = true diff --git a/config/testdata/enableAllWithRule.toml b/config/testdata/enableAllWithRule.toml new file mode 100644 index 0000000..d9510ef --- /dev/null +++ b/config/testdata/enableAllWithRule.toml @@ -0,0 +1,4 @@ +enableAllRules = true + +# Explicitly add a rule that's already in allRules +[rule.cyclomatic] diff --git a/config/testdata/enableDefault.toml b/config/testdata/enableDefault.toml new file mode 100644 index 0000000..5988ba1 --- /dev/null +++ b/config/testdata/enableDefault.toml @@ -0,0 +1,3 @@ +# Enable only default rules + +enableDefaultRules = true diff --git a/config/testdata/enableDefaultBut2.toml b/config/testdata/enableDefaultBut2.toml new file mode 100644 index 0000000..21d338e --- /dev/null +++ b/config/testdata/enableDefaultBut2.toml @@ -0,0 +1,9 @@ +# Enable default without 2 default rules + +enableDefaultRules = true + +# Disable a few default rules +[rule.exported] +Disabled = true +[rule.indent-error-flow] +Disabled = true diff --git a/config/testdata/enableDefaultPlus1.toml b/config/testdata/enableDefaultPlus1.toml new file mode 100644 index 0000000..5471487 --- /dev/null +++ b/config/testdata/enableDefaultPlus1.toml @@ -0,0 +1,6 @@ +# Enable default rules with a non-default rule + +enableDefaultRules = true + +# Add a non-default rule +[rule.cyclomatic] diff --git a/config/testdata/enableDefaultPlusDefaultRule.toml b/config/testdata/enableDefaultPlusDefaultRule.toml new file mode 100644 index 0000000..94ab974 --- /dev/null +++ b/config/testdata/enableDefaultPlusDefaultRule.toml @@ -0,0 +1,6 @@ +# Enable default rules + +enableDefaultRules = true + +# Explicitly add a rule that's already in defaults +[rule.exported] diff --git a/lint/config.go b/lint/config.go index ae9a20a..3047fd2 100644 --- a/lint/config.go +++ b/lint/config.go @@ -60,6 +60,7 @@ type Config struct { Confidence float64 `toml:"confidence"` Severity Severity `toml:"severity"` EnableAllRules bool `toml:"enableAllRules"` + EnableDefaultRules bool `toml:"enableDefaultRules"` Rules RulesConfig `toml:"rule"` ErrorCode int `toml:"errorCode"` WarningCode int `toml:"warningCode"`