Skip to content

Commit ec52d3c

Browse files
authored
feat: syntax to not override severity from linters (#4472)
1 parent bb30bbe commit ec52d3c

File tree

6 files changed

+211
-27
lines changed

6 files changed

+211
-27
lines changed

.golangci.reference.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2881,20 +2881,21 @@ severity:
28812881
# - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
28822882
# - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
28832883
#
2884+
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
2885+
#
28842886
# Default: ""
28852887
default-severity: error
28862888

28872889
# If set to true `severity-rules` regular expressions become case-sensitive.
28882890
# Default: false
28892891
case-sensitive: true
28902892

2891-
# Don't override severity defined by linters.
2892-
# Default: false
2893-
keep-linter-severity: true
2894-
28952893
# When a list of severity rules are provided, severity information will be added to lint issues.
28962894
# Severity rules have the same filtering capability as exclude rules
28972895
# except you are allowed to specify one matcher per severity rule.
2896+
#
2897+
# `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
2898+
#
28982899
# Only affects out formats that support setting severity information.
28992900
#
29002901
# Default: []

pkg/config/severity.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ import (
88
const severityRuleMinConditionsCount = 1
99

1010
type Severity struct {
11-
Default string `mapstructure:"default-severity"`
12-
CaseSensitive bool `mapstructure:"case-sensitive"`
13-
Rules []SeverityRule `mapstructure:"rules"`
14-
KeepLinterSeverity bool `mapstructure:"keep-linter-severity"` // TODO(ldez): in v2 should be changed to `Override`.
11+
Default string `mapstructure:"default-severity"`
12+
CaseSensitive bool `mapstructure:"case-sensitive"`
13+
Rules []SeverityRule `mapstructure:"rules"`
1514
}
1615

1716
func (s *Severity) Validate() error {

pkg/lint/runner.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ func getSeverityRulesProcessor(cfg *config.Severity, log logutils.Log, files *fs
302302
Default: cfg.Default,
303303
Rules: severityRules,
304304
CaseSensitive: cfg.CaseSensitive,
305-
Override: !cfg.KeepLinterSeverity,
306305
}
307306

308307
return processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, severityOpts)

pkg/result/processors/processor_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func newIssueFromIssueTestCase(c issueTestCase) result.Issue {
2222
return result.Issue{
2323
Text: c.Text,
2424
FromLinter: c.Linter,
25+
Severity: c.Severity,
2526
Pos: token.Position{
2627
Filename: c.Path,
2728
Line: c.Line,

pkg/result/processors/severity.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"github.com/golangci/golangci-lint/pkg/result"
99
)
1010

11+
const severityFromLinter = "@linter"
12+
1113
var _ Processor = &Severity{}
1214

1315
type severityRule struct {
@@ -24,7 +26,6 @@ type SeverityOptions struct {
2426
Default string
2527
Rules []SeverityRule
2628
CaseSensitive bool
27-
Override bool
2829
}
2930

3031
type Severity struct {
@@ -36,7 +37,6 @@ type Severity struct {
3637

3738
defaultSeverity string
3839
rules []severityRule
39-
override bool
4040
}
4141

4242
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) *
4545
files: files,
4646
log: log,
4747
defaultSeverity: opts.Default,
48-
override: opts.Override,
4948
}
5049

5150
prefix := caseInsensitivePrefix
@@ -64,29 +63,30 @@ func (p *Severity) Process(issues []result.Issue) ([]result.Issue, error) {
6463
return issues, nil
6564
}
6665

67-
return transformIssues(issues, func(issue *result.Issue) *result.Issue {
68-
if issue.Severity != "" && !p.override {
69-
return issue
70-
}
71-
72-
for _, rule := range p.rules {
73-
rule := rule
66+
return transformIssues(issues, p.transform), nil
67+
}
7468

75-
ruleSeverity := p.defaultSeverity
76-
if rule.severity != "" {
77-
ruleSeverity = rule.severity
69+
func (p *Severity) transform(issue *result.Issue) *result.Issue {
70+
for _, rule := range p.rules {
71+
if rule.match(issue, p.files, p.log) {
72+
if rule.severity == severityFromLinter || rule.severity == "" && p.defaultSeverity == severityFromLinter {
73+
return issue
7874
}
7975

80-
if rule.match(issue, p.files, p.log) {
81-
issue.Severity = ruleSeverity
82-
return issue
76+
issue.Severity = rule.severity
77+
if issue.Severity == "" {
78+
issue.Severity = p.defaultSeverity
8379
}
80+
81+
return issue
8482
}
83+
}
8584

85+
if p.defaultSeverity != severityFromLinter {
8686
issue.Severity = p.defaultSeverity
87+
}
8788

88-
return issue
89-
}), nil
89+
return issue
9090
}
9191

9292
func (p *Severity) Name() string { return p.name }

pkg/result/processors/severity_test.go

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,187 @@ func TestSeverity_caseSensitive(t *testing.T) {
310310

311311
assert.Equal(t, expectedCases, resultingCases)
312312
}
313+
314+
func TestSeverity_transform(t *testing.T) {
315+
lineCache := fsutils.NewLineCache(fsutils.NewFileCache())
316+
files := fsutils.NewFiles(lineCache, "")
317+
318+
testCases := []struct {
319+
desc string
320+
opts SeverityOptions
321+
issue *result.Issue
322+
expected *result.Issue
323+
}{
324+
{
325+
desc: "apply severity from rule",
326+
opts: SeverityOptions{
327+
Default: "error",
328+
Rules: []SeverityRule{
329+
{
330+
Severity: "info",
331+
BaseRule: BaseRule{
332+
Linters: []string{"linter1"},
333+
},
334+
},
335+
},
336+
},
337+
issue: &result.Issue{
338+
Text: "This is a report",
339+
FromLinter: "linter1",
340+
},
341+
expected: &result.Issue{
342+
Text: "This is a report",
343+
FromLinter: "linter1",
344+
Severity: "info",
345+
},
346+
},
347+
{
348+
desc: "apply severity from default",
349+
opts: SeverityOptions{
350+
Default: "error",
351+
Rules: []SeverityRule{
352+
{
353+
Severity: "info",
354+
BaseRule: BaseRule{
355+
Linters: []string{"linter1"},
356+
},
357+
},
358+
},
359+
},
360+
issue: &result.Issue{
361+
Text: "This is a report",
362+
FromLinter: "linter2",
363+
},
364+
expected: &result.Issue{
365+
Text: "This is a report",
366+
FromLinter: "linter2",
367+
Severity: "error",
368+
},
369+
},
370+
{
371+
desc: "severity from rule override severity from linter",
372+
opts: SeverityOptions{
373+
Default: "error",
374+
Rules: []SeverityRule{
375+
{
376+
Severity: "info",
377+
BaseRule: BaseRule{
378+
Linters: []string{"linter1"},
379+
},
380+
},
381+
},
382+
},
383+
issue: &result.Issue{
384+
Text: "This is a report",
385+
FromLinter: "linter1",
386+
Severity: "huge",
387+
},
388+
expected: &result.Issue{
389+
Text: "This is a report",
390+
FromLinter: "linter1",
391+
Severity: "info",
392+
},
393+
},
394+
{
395+
desc: "severity from default override severity from linter",
396+
opts: SeverityOptions{
397+
Default: "error",
398+
Rules: []SeverityRule{
399+
{
400+
Severity: "info",
401+
BaseRule: BaseRule{
402+
Linters: []string{"linter1"},
403+
},
404+
},
405+
},
406+
},
407+
issue: &result.Issue{
408+
Text: "This is a report",
409+
FromLinter: "linter2",
410+
Severity: "huge",
411+
},
412+
expected: &result.Issue{
413+
Text: "This is a report",
414+
FromLinter: "linter2",
415+
Severity: "error",
416+
},
417+
},
418+
{
419+
desc: "keep severity from linter as rule",
420+
opts: SeverityOptions{
421+
Default: "error",
422+
Rules: []SeverityRule{
423+
{
424+
Severity: severityFromLinter,
425+
BaseRule: BaseRule{
426+
Linters: []string{"linter1"},
427+
},
428+
},
429+
},
430+
},
431+
issue: &result.Issue{
432+
Text: "This is a report",
433+
FromLinter: "linter1",
434+
Severity: "huge",
435+
},
436+
expected: &result.Issue{
437+
Text: "This is a report",
438+
FromLinter: "linter1",
439+
Severity: "huge",
440+
},
441+
},
442+
{
443+
desc: "keep severity from linter as default",
444+
opts: SeverityOptions{
445+
Default: severityFromLinter,
446+
Rules: []SeverityRule{
447+
{
448+
Severity: "info",
449+
BaseRule: BaseRule{
450+
Linters: []string{"linter1"},
451+
},
452+
},
453+
},
454+
},
455+
issue: &result.Issue{
456+
Text: "This is a report",
457+
FromLinter: "linter2",
458+
Severity: "huge",
459+
},
460+
expected: &result.Issue{
461+
Text: "This is a report",
462+
FromLinter: "linter2",
463+
Severity: "huge",
464+
},
465+
},
466+
{
467+
desc: "keep severity from linter as default (without rule)",
468+
opts: SeverityOptions{
469+
Default: severityFromLinter,
470+
},
471+
issue: &result.Issue{
472+
Text: "This is a report",
473+
FromLinter: "linter2",
474+
Severity: "huge",
475+
},
476+
expected: &result.Issue{
477+
Text: "This is a report",
478+
FromLinter: "linter2",
479+
Severity: "huge",
480+
},
481+
},
482+
}
483+
484+
for _, test := range testCases {
485+
test := test
486+
t.Run(test.desc, func(t *testing.T) {
487+
t.Parallel()
488+
489+
p := NewSeverity(nil, files, test.opts)
490+
491+
newIssue := p.transform(test.issue)
492+
493+
assert.Equal(t, test.expected, newIssue)
494+
})
495+
}
496+
}

0 commit comments

Comments
 (0)