feat: syntax to not override severity from linters (#4472)
This commit is contained in:
parent
bb30bbe658
commit
ec52d3c881
@ -2881,6 +2881,8 @@ severity:
|
|||||||
# - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
|
# - 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
|
# - 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: ""
|
||||||
default-severity: error
|
default-severity: error
|
||||||
|
|
||||||
@ -2888,13 +2890,12 @@ severity:
|
|||||||
# Default: false
|
# Default: false
|
||||||
case-sensitive: true
|
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.
|
# 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
|
# Severity rules have the same filtering capability as exclude rules
|
||||||
# except you are allowed to specify one matcher per severity rule.
|
# 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.
|
# Only affects out formats that support setting severity information.
|
||||||
#
|
#
|
||||||
# Default: []
|
# Default: []
|
||||||
|
@ -8,10 +8,9 @@ import (
|
|||||||
const severityRuleMinConditionsCount = 1
|
const severityRuleMinConditionsCount = 1
|
||||||
|
|
||||||
type Severity struct {
|
type Severity struct {
|
||||||
Default string `mapstructure:"default-severity"`
|
Default string `mapstructure:"default-severity"`
|
||||||
CaseSensitive bool `mapstructure:"case-sensitive"`
|
CaseSensitive bool `mapstructure:"case-sensitive"`
|
||||||
Rules []SeverityRule `mapstructure:"rules"`
|
Rules []SeverityRule `mapstructure:"rules"`
|
||||||
KeepLinterSeverity bool `mapstructure:"keep-linter-severity"` // TODO(ldez): in v2 should be changed to `Override`.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Severity) Validate() error {
|
func (s *Severity) Validate() error {
|
||||||
|
@ -302,7 +302,6 @@ func getSeverityRulesProcessor(cfg *config.Severity, log logutils.Log, files *fs
|
|||||||
Default: cfg.Default,
|
Default: cfg.Default,
|
||||||
Rules: severityRules,
|
Rules: severityRules,
|
||||||
CaseSensitive: cfg.CaseSensitive,
|
CaseSensitive: cfg.CaseSensitive,
|
||||||
Override: !cfg.KeepLinterSeverity,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, severityOpts)
|
return processors.NewSeverity(log.Child(logutils.DebugKeySeverityRules), files, severityOpts)
|
||||||
|
@ -22,6 +22,7 @@ func newIssueFromIssueTestCase(c issueTestCase) result.Issue {
|
|||||||
return result.Issue{
|
return result.Issue{
|
||||||
Text: c.Text,
|
Text: c.Text,
|
||||||
FromLinter: c.Linter,
|
FromLinter: c.Linter,
|
||||||
|
Severity: c.Severity,
|
||||||
Pos: token.Position{
|
Pos: token.Position{
|
||||||
Filename: c.Path,
|
Filename: c.Path,
|
||||||
Line: c.Line,
|
Line: c.Line,
|
||||||
|
@ -8,6 +8,8 @@ import (
|
|||||||
"github.com/golangci/golangci-lint/pkg/result"
|
"github.com/golangci/golangci-lint/pkg/result"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const severityFromLinter = "@linter"
|
||||||
|
|
||||||
var _ Processor = &Severity{}
|
var _ Processor = &Severity{}
|
||||||
|
|
||||||
type severityRule struct {
|
type severityRule struct {
|
||||||
@ -24,7 +26,6 @@ type SeverityOptions struct {
|
|||||||
Default string
|
Default string
|
||||||
Rules []SeverityRule
|
Rules []SeverityRule
|
||||||
CaseSensitive bool
|
CaseSensitive bool
|
||||||
Override bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Severity struct {
|
type Severity struct {
|
||||||
@ -36,7 +37,6 @@ type Severity struct {
|
|||||||
|
|
||||||
defaultSeverity string
|
defaultSeverity string
|
||||||
rules []severityRule
|
rules []severityRule
|
||||||
override bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSeverity(log logutils.Log, files *fsutils.Files, opts SeverityOptions) *Severity {
|
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,
|
files: files,
|
||||||
log: log,
|
log: log,
|
||||||
defaultSeverity: opts.Default,
|
defaultSeverity: opts.Default,
|
||||||
override: opts.Override,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix := caseInsensitivePrefix
|
prefix := caseInsensitivePrefix
|
||||||
@ -64,29 +63,30 @@ func (p *Severity) Process(issues []result.Issue) ([]result.Issue, error) {
|
|||||||
return issues, nil
|
return issues, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformIssues(issues, func(issue *result.Issue) *result.Issue {
|
return transformIssues(issues, p.transform), nil
|
||||||
if issue.Severity != "" && !p.override {
|
}
|
||||||
return issue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rule := range p.rules {
|
func (p *Severity) transform(issue *result.Issue) *result.Issue {
|
||||||
rule := rule
|
for _, rule := range p.rules {
|
||||||
|
if rule.match(issue, p.files, p.log) {
|
||||||
ruleSeverity := p.defaultSeverity
|
if rule.severity == severityFromLinter || rule.severity == "" && p.defaultSeverity == severityFromLinter {
|
||||||
if rule.severity != "" {
|
|
||||||
ruleSeverity = rule.severity
|
|
||||||
}
|
|
||||||
|
|
||||||
if rule.match(issue, p.files, p.log) {
|
|
||||||
issue.Severity = ruleSeverity
|
|
||||||
return issue
|
return issue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue.Severity = rule.severity
|
||||||
|
if issue.Severity == "" {
|
||||||
|
issue.Severity = p.defaultSeverity
|
||||||
|
}
|
||||||
|
|
||||||
|
return issue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.defaultSeverity != severityFromLinter {
|
||||||
issue.Severity = p.defaultSeverity
|
issue.Severity = p.defaultSeverity
|
||||||
|
}
|
||||||
|
|
||||||
return issue
|
return issue
|
||||||
}), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Severity) Name() string { return p.name }
|
func (p *Severity) Name() string { return p.name }
|
||||||
|
@ -310,3 +310,187 @@ func TestSeverity_caseSensitive(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, expectedCases, resultingCases)
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user