diff --git a/.golangci.reference.yml b/.golangci.reference.yml index 6a6239774b19..27293fb8948e 100644 --- a/.golangci.reference.yml +++ b/.golangci.reference.yml @@ -2881,6 +2881,8 @@ severity: # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # # Default: "" default-severity: error @@ -2888,13 +2890,12 @@ severity: # Default: false case-sensitive: true - # Don't override severity defined by linters. - # Default: false - keep-linter-severity: true - # When a list of severity rules are provided, severity information will be added to lint issues. # Severity rules have the same filtering capability as exclude rules # except you are allowed to specify one matcher per severity rule. + # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # # Only affects out formats that support setting severity information. # # Default: [] diff --git a/pkg/config/severity.go b/pkg/config/severity.go index 49874c9a4c3a..a6d2c9ec3fb3 100644 --- a/pkg/config/severity.go +++ b/pkg/config/severity.go @@ -8,10 +8,9 @@ import ( const severityRuleMinConditionsCount = 1 type Severity struct { - Default string `mapstructure:"default-severity"` - CaseSensitive bool `mapstructure:"case-sensitive"` - Rules []SeverityRule `mapstructure:"rules"` - KeepLinterSeverity bool `mapstructure:"keep-linter-severity"` // TODO(ldez): in v2 should be changed to `Override`. + Default string `mapstructure:"default-severity"` + CaseSensitive bool `mapstructure:"case-sensitive"` + Rules []SeverityRule `mapstructure:"rules"` } func (s *Severity) Validate() error { diff --git a/pkg/lint/runner.go b/pkg/lint/runner.go index 78be9382dac4..13daa3b3b6cd 100644 --- a/pkg/lint/runner.go +++ b/pkg/lint/runner.go @@ -302,7 +302,6 @@ func getSeverityRulesProcessor(cfg *config.Severity, log logutils.Log, files *fs Default: cfg.Default, Rules: severityRules, CaseSensitive: cfg.CaseSensitive, - Override: !cfg.KeepLinterSeverity, } return processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, severityOpts) diff --git a/pkg/result/processors/processor_test.go b/pkg/result/processors/processor_test.go index d263cf294b85..216a8fcd5997 100644 --- a/pkg/result/processors/processor_test.go +++ b/pkg/result/processors/processor_test.go @@ -22,6 +22,7 @@ func newIssueFromIssueTestCase(c issueTestCase) result.Issue { return result.Issue{ Text: c.Text, FromLinter: c.Linter, + Severity: c.Severity, Pos: token.Position{ Filename: c.Path, Line: c.Line, diff --git a/pkg/result/processors/severity.go b/pkg/result/processors/severity.go index 943b14a429db..f087f951b7f2 100644 --- a/pkg/result/processors/severity.go +++ b/pkg/result/processors/severity.go @@ -8,6 +8,8 @@ import ( "github.com/golangci/golangci-lint/pkg/result" ) +const severityFromLinter = "@linter" + var _ Processor = &Severity{} type severityRule struct { @@ -24,7 +26,6 @@ type SeverityOptions struct { Default string Rules []SeverityRule CaseSensitive bool - Override bool } type Severity struct { @@ -36,7 +37,6 @@ type Severity struct { defaultSeverity string rules []severityRule - override bool } func NewSeverity(log logutils.Log, files *fsutils.Files, opts SeverityOptions) *Severity { @@ -45,7 +45,6 @@ func NewSeverity(log logutils.Log, files *fsutils.Files, opts SeverityOptions) * files: files, log: log, defaultSeverity: opts.Default, - override: opts.Override, } prefix := caseInsensitivePrefix @@ -64,29 +63,30 @@ func (p *Severity) Process(issues []result.Issue) ([]result.Issue, error) { return issues, nil } - return transformIssues(issues, func(issue *result.Issue) *result.Issue { - if issue.Severity != "" && !p.override { - return issue - } - - for _, rule := range p.rules { - rule := rule + return transformIssues(issues, p.transform), nil +} - ruleSeverity := p.defaultSeverity - if rule.severity != "" { - ruleSeverity = rule.severity +func (p *Severity) transform(issue *result.Issue) *result.Issue { + for _, rule := range p.rules { + if rule.match(issue, p.files, p.log) { + if rule.severity == severityFromLinter || rule.severity == "" && p.defaultSeverity == severityFromLinter { + return issue } - if rule.match(issue, p.files, p.log) { - issue.Severity = ruleSeverity - return issue + issue.Severity = rule.severity + if issue.Severity == "" { + issue.Severity = p.defaultSeverity } + + return issue } + } + if p.defaultSeverity != severityFromLinter { issue.Severity = p.defaultSeverity + } - return issue - }), nil + return issue } func (p *Severity) Name() string { return p.name } diff --git a/pkg/result/processors/severity_test.go b/pkg/result/processors/severity_test.go index 9690b5505edd..cbf18e6c79ae 100644 --- a/pkg/result/processors/severity_test.go +++ b/pkg/result/processors/severity_test.go @@ -310,3 +310,187 @@ func TestSeverity_caseSensitive(t *testing.T) { assert.Equal(t, expectedCases, resultingCases) } + +func TestSeverity_transform(t *testing.T) { + lineCache := fsutils.NewLineCache(fsutils.NewFileCache()) + files := fsutils.NewFiles(lineCache, "") + + testCases := []struct { + desc string + opts SeverityOptions + issue *result.Issue + expected *result.Issue + }{ + { + desc: "apply severity from rule", + opts: SeverityOptions{ + Default: "error", + Rules: []SeverityRule{ + { + Severity: "info", + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + Severity: "info", + }, + }, + { + desc: "apply severity from default", + opts: SeverityOptions{ + Default: "error", + Rules: []SeverityRule{ + { + Severity: "info", + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "error", + }, + }, + { + desc: "severity from rule override severity from linter", + opts: SeverityOptions{ + Default: "error", + Rules: []SeverityRule{ + { + Severity: "info", + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + Severity: "huge", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + Severity: "info", + }, + }, + { + desc: "severity from default override severity from linter", + opts: SeverityOptions{ + Default: "error", + Rules: []SeverityRule{ + { + Severity: "info", + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "huge", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "error", + }, + }, + { + desc: "keep severity from linter as rule", + opts: SeverityOptions{ + Default: "error", + Rules: []SeverityRule{ + { + Severity: severityFromLinter, + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + Severity: "huge", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter1", + Severity: "huge", + }, + }, + { + desc: "keep severity from linter as default", + opts: SeverityOptions{ + Default: severityFromLinter, + Rules: []SeverityRule{ + { + Severity: "info", + BaseRule: BaseRule{ + Linters: []string{"linter1"}, + }, + }, + }, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "huge", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "huge", + }, + }, + { + desc: "keep severity from linter as default (without rule)", + opts: SeverityOptions{ + Default: severityFromLinter, + }, + issue: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "huge", + }, + expected: &result.Issue{ + Text: "This is a report", + FromLinter: "linter2", + Severity: "huge", + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + p := NewSeverity(nil, files, test.opts) + + newIssue := p.transform(test.issue) + + assert.Equal(t, test.expected, newIssue) + }) + } +}