Skip to content

dev: factorize base rule parsing #5360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions pkg/result/processors/base_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package processors
import (
"regexp"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/fsutils"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/pkg/result"
Expand All @@ -16,9 +17,32 @@ type baseRule struct {
path *regexp.Regexp
pathExcept *regexp.Regexp
linters []string
}

// The usage of `regexp.MustCompile()` is safe here,
// because the regular expressions are checked before inside [config.BaseRule.Validate].
func newBaseRule(rule *config.BaseRule, prefix string) baseRule {
base := baseRule{
linters: rule.Linters,
}

if rule.Text != "" {
base.text = regexp.MustCompile(prefix + rule.Text)
}

if rule.Source != "" {
base.source = regexp.MustCompile(prefix + rule.Source)
}

if rule.Path != "" {
base.path = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.Path))
}

// For compatibility with exclude-use-default/include.
internalReference string `mapstructure:"-"`
if rule.PathExcept != "" {
base.pathExcept = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.PathExcept))
}

return base
}

func (r *baseRule) isEmpty() bool {
Expand Down Expand Up @@ -69,3 +93,17 @@ func (r *baseRule) matchSource(issue *result.Issue, lineCache *fsutils.LineCache

return r.source.MatchString(sourceLine)
}

func parseRules[T, V any](rules []T, prefix string, newFn func(*T, string) V) []V {
if len(rules) == 0 {
return nil
}

parsedRules := make([]V, 0, len(rules))

for _, r := range rules {
parsedRules = append(parsedRules, newFn(&r, prefix))
}

return parsedRules
}
54 changes: 14 additions & 40 deletions pkg/result/processors/exclusion_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package processors

import (
"fmt"
"regexp"
"slices"
"strings"

Expand All @@ -24,7 +23,8 @@ type ExclusionRules struct {
rules []excludeRule
}

func NewExclusionRules(log logutils.Log, files *fsutils.Files, cfg *config.LinterExclusions, oldCfg *config.Issues) *ExclusionRules {
func NewExclusionRules(log logutils.Log, files *fsutils.Files,
cfg *config.LinterExclusions, oldCfg *config.Issues) *ExclusionRules {
p := &ExclusionRules{
log: log,
files: files,
Expand All @@ -41,20 +41,22 @@ func NewExclusionRules(log logutils.Log, files *fsutils.Files, cfg *config.Linte
excludeRules := slices.Concat(slices.Clone(cfg.Rules),
filterInclude(getLinterExclusionPresets(cfg.Presets), oldCfg.IncludeDefaultExcludes))

p.rules = createExcludeRules(excludeRules, prefix)
p.rules = parseRules(excludeRules, prefix, newExcludeRule)

// TODO(ldez): should be removed in v2.
for _, pattern := range oldCfg.ExcludePatterns {
if pattern == "" {
continue
}

rule := newRule(&config.ExcludeRule{
r := &config.ExcludeRule{
BaseRule: config.BaseRule{
Path: `.+\.go`,
Text: pattern,
},
}, prefix)
}

rule := newExcludeRule(r, prefix)

p.rules = append(p.rules, rule)
}
Expand Down Expand Up @@ -107,30 +109,16 @@ func (p *ExclusionRules) Finish() {

type excludeRule struct {
baseRule
}

func newRule(rule *config.ExcludeRule, prefix string) excludeRule {
parsedRule := excludeRule{}
parsedRule.linters = rule.Linters
parsedRule.internalReference = rule.InternalReference

if rule.Text != "" {
parsedRule.text = regexp.MustCompile(prefix + rule.Text)
}

if rule.Source != "" {
parsedRule.source = regexp.MustCompile(prefix + rule.Source)
}

if rule.Path != "" {
parsedRule.path = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.Path))
}
// For compatibility with exclude-use-default/include.
internalReference string `mapstructure:"-"`
}

if rule.PathExcept != "" {
parsedRule.pathExcept = regexp.MustCompile(fsutils.NormalizePathInRegex(rule.PathExcept))
func newExcludeRule(rule *config.ExcludeRule, prefix string) excludeRule {
return excludeRule{
baseRule: newBaseRule(&rule.BaseRule, prefix),
internalReference: rule.InternalReference,
}

return parsedRule
}

func (e excludeRule) String() string {
Expand Down Expand Up @@ -159,20 +147,6 @@ func (e excludeRule) String() string {
return strings.Join(msg, ", ")
}

func createExcludeRules(rules []config.ExcludeRule, prefix string) []excludeRule {
if len(rules) == 0 {
return nil
}

parsedRules := make([]excludeRule, 0, len(rules))

for _, rule := range rules {
parsedRules = append(parsedRules, newRule(&rule, prefix))
}

return parsedRules
}

// TODO(ldez): must be removed in v2, only for compatibility with exclude-use-default/include.
func filterInclude(rules []config.ExcludeRule, refs []string) []config.ExcludeRule {
if len(refs) == 0 {
Expand Down
44 changes: 9 additions & 35 deletions pkg/result/processors/severity.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package processors

import (
"cmp"
"regexp"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/fsutils"
Expand All @@ -14,11 +13,6 @@ const severityFromLinter = "@linter"

var _ Processor = (*Severity)(nil)

type severityRule struct {
baseRule
severity string
}

// Severity modifies report severity.
// It uses the same `baseRule` structure as [ExcludeRules] processor.
//
Expand Down Expand Up @@ -48,7 +42,7 @@ func NewSeverity(log logutils.Log, files *fsutils.Files, cfg *config.Severity) *
p.name = "severity-rules-case-sensitive"
}

p.rules = createSeverityRules(cfg.Rules, prefix)
p.rules = parseRules(cfg.Rules, prefix, newSeverityRule)

return p
}
Expand Down Expand Up @@ -85,34 +79,14 @@ func (p *Severity) transform(issue *result.Issue) *result.Issue {
return issue
}

func createSeverityRules(rules []config.SeverityRule, prefix string) []severityRule {
parsedRules := make([]severityRule, 0, len(rules))

for _, rule := range rules {
parsedRule := severityRule{}
parsedRule.linters = rule.Linters
parsedRule.severity = rule.Severity

if rule.Text != "" {
parsedRule.text = regexp.MustCompile(prefix + rule.Text)
}

if rule.Source != "" {
parsedRule.source = regexp.MustCompile(prefix + rule.Source)
}

if rule.Path != "" {
path := fsutils.NormalizePathInRegex(rule.Path)
parsedRule.path = regexp.MustCompile(path)
}

if rule.PathExcept != "" {
pathExcept := fsutils.NormalizePathInRegex(rule.PathExcept)
parsedRule.pathExcept = regexp.MustCompile(pathExcept)
}
type severityRule struct {
baseRule
severity string
}

parsedRules = append(parsedRules, parsedRule)
func newSeverityRule(rule *config.SeverityRule, prefix string) severityRule {
return severityRule{
baseRule: newBaseRule(&rule.BaseRule, prefix),
severity: rule.Severity,
}

return parsedRules
}
Loading