115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package processors
|
|
|
|
import (
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
|
"github.com/golangci/golangci-lint/pkg/result"
|
|
)
|
|
|
|
type SkipDirs struct {
|
|
patterns []*regexp.Regexp
|
|
log logutils.Log
|
|
skippedDirs map[string]string // dir to the last regexp mapping
|
|
absArgsDirs []string
|
|
}
|
|
|
|
var _ Processor = SkipFiles{}
|
|
|
|
const goFileSuffix = ".go"
|
|
|
|
func NewSkipDirs(patterns []string, log logutils.Log, runArgs []string) (*SkipDirs, error) {
|
|
var patternsRe []*regexp.Regexp
|
|
for _, p := range patterns {
|
|
patternRe, err := regexp.Compile(p)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "can't compile regexp %q", p)
|
|
}
|
|
patternsRe = append(patternsRe, patternRe)
|
|
}
|
|
|
|
if len(runArgs) == 0 {
|
|
runArgs = append(runArgs, "./...")
|
|
}
|
|
var absArgsDirs []string
|
|
for _, arg := range runArgs {
|
|
base := filepath.Base(arg)
|
|
if base == "..." || strings.HasSuffix(base, goFileSuffix) {
|
|
arg = filepath.Dir(arg)
|
|
}
|
|
|
|
absArg, err := filepath.Abs(arg)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "failed to abs-ify arg %q", arg)
|
|
}
|
|
absArgsDirs = append(absArgsDirs, absArg)
|
|
}
|
|
|
|
return &SkipDirs{
|
|
patterns: patternsRe,
|
|
log: log,
|
|
skippedDirs: map[string]string{},
|
|
absArgsDirs: absArgsDirs,
|
|
}, nil
|
|
}
|
|
|
|
func (p SkipDirs) Name() string {
|
|
return "skip_dirs"
|
|
}
|
|
|
|
func (p *SkipDirs) Process(issues []result.Issue) ([]result.Issue, error) {
|
|
if len(p.patterns) == 0 {
|
|
return issues, nil
|
|
}
|
|
|
|
return filterIssues(issues, p.shouldPassIssue), nil
|
|
}
|
|
|
|
func (p *SkipDirs) shouldPassIssue(i *result.Issue) bool {
|
|
if filepath.IsAbs(i.FilePath()) {
|
|
p.log.Warnf("Got abs path in skip dirs processor, it should be relative")
|
|
return true
|
|
}
|
|
|
|
issueRelDir := filepath.Dir(i.FilePath())
|
|
issueAbsDir, err := filepath.Abs(issueRelDir)
|
|
if err != nil {
|
|
p.log.Warnf("Can't abs-ify path %q: %s", issueRelDir, err)
|
|
return true
|
|
}
|
|
|
|
for _, absArgDir := range p.absArgsDirs {
|
|
if absArgDir == issueAbsDir {
|
|
// we must not skip issues if they are from explicitly set dirs
|
|
// even if they match skip patterns
|
|
return true
|
|
}
|
|
}
|
|
|
|
// We use issueRelDir for matching: it's the relative to the current
|
|
// work dir path of directory of source file with the issue. It can lead
|
|
// to unexpected behavior if we're analyzing files out of current work dir.
|
|
// The alternative solution is to find relative to args path, but it has
|
|
// disadvantages (https://github.com/golangci/golangci-lint/pull/313).
|
|
|
|
for _, pattern := range p.patterns {
|
|
if pattern.MatchString(issueRelDir) {
|
|
ps := pattern.String()
|
|
p.skippedDirs[issueRelDir] = ps
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func (p SkipDirs) Finish() {
|
|
for dir, pattern := range p.skippedDirs {
|
|
p.log.Infof("Skipped dir %s by pattern %s", dir, pattern)
|
|
}
|
|
}
|