implement max issues per linter limiting

This commit is contained in:
golangci 2018-05-08 08:15:55 +03:00
parent 4853151835
commit 393733fa6a
11 changed files with 79 additions and 0 deletions

View File

@ -81,6 +81,8 @@ func (e *Executor) initRun() {
runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Second*30, "Deadline for total work")
runCmd.Flags().StringSliceVarP(&rc.ExcludePatterns, "exclude", "e", config.DefaultExcludePatterns, "Exclude issue by regexp")
runCmd.Flags().IntVar(&rc.MaxIssuesPerLinter, "max-issues-per-linter", 50, "Maximum issues count per one linter. Set to 0 to disable")
}
func isFullImportNeeded(linters []pkg.Linter) bool {
@ -198,6 +200,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (chan result.
processors.NewExclude(fmt.Sprintf("(%s)", strings.Join(e.cfg.Run.ExcludePatterns, "|"))),
processors.NewNolint(lintCtx.Program.Fset),
processors.NewUniqByLine(),
processors.NewMaxFromLinter(e.cfg.Run.MaxIssuesPerLinter),
processors.NewPathPrettifier(),
},
}

View File

@ -77,6 +77,8 @@ type Run struct {
ExcludePatterns []string
Deadline time.Duration
MaxIssuesPerLinter int
}
type Config struct {

View File

@ -35,3 +35,5 @@ func (p Exclude) Process(issues []result.Issue) ([]result.Issue, error) {
return !p.pattern.MatchString(i.Text)
}), nil
}
func (p Exclude) Finish() {}

View File

@ -0,0 +1,44 @@
package processors
import (
"github.com/golangci/golangci-lint/pkg/result"
"github.com/sirupsen/logrus"
)
type MaxFromLinter struct {
lc linterToCountMap
limit int
}
var _ Processor = &MaxFromLinter{}
func NewMaxFromLinter(limit int) *MaxFromLinter {
return &MaxFromLinter{
lc: linterToCountMap{},
limit: limit,
}
}
func (p MaxFromLinter) Name() string {
return "max_from_linter"
}
func (p *MaxFromLinter) Process(issues []result.Issue) ([]result.Issue, error) {
if p.limit <= 0 { // no limit
return issues, nil
}
return filterIssues(issues, func(i *result.Issue) bool {
p.lc[i.FromLinter]++ // always inc for stat
return p.lc[i.FromLinter] <= p.limit
}), nil
}
func (p MaxFromLinter) Finish() {
for linter, count := range p.lc {
if count > p.limit {
logrus.Infof("%d/%d issues from linter %s were hidden, use --max-issues-per-linter",
count-p.limit, count, linter)
}
}
}

View File

@ -0,0 +1,14 @@
package processors
import (
"testing"
)
func TestMaxFromLinter(t *testing.T) {
p := NewMaxFromLinter(1)
gosimple := newFromLinterIssue("gosimple")
gofmt := newFromLinterIssue("gofmt")
processAssertSame(t, p, gosimple) // ok
processAssertSame(t, p, gofmt) // ok: another
processAssertEmpty(t, p, gosimple) // skip
}

View File

@ -49,3 +49,5 @@ func (p *MaxPerFileFromLinter) Process(issues []result.Issue) ([]result.Issue, e
return true
}), nil
}
func (p MaxPerFileFromLinter) Finish() {}

View File

@ -94,3 +94,5 @@ func extractFileComments(fset *token.FileSet, comments ...*ast.CommentGroup) fil
return ret
}
func (p Nolint) Finish() {}

View File

@ -44,3 +44,5 @@ func (p PathPrettifier) Process(issues []result.Issue) ([]result.Issue, error) {
return newI
}), nil
}
func (p PathPrettifier) Finish() {}

View File

@ -5,4 +5,5 @@ import "github.com/golangci/golangci-lint/pkg/result"
type Processor interface {
Process(issues []result.Issue) ([]result.Issue, error)
Name() string
Finish()
}

View File

@ -41,3 +41,5 @@ func (p *UniqByLine) Process(issues []result.Issue) ([]result.Issue, error) {
return true
}), nil
}
func (p UniqByLine) Finish() {}

View File

@ -125,6 +125,11 @@ func (r SimpleRunner) runGo(ctx context.Context, linters []Linter, lintCtx *goli
}
}
// finalize processors: logging, clearing, no heavy work here
for _, p := range r.Processors {
p.Finish()
}
if ctx.Err() != nil {
return fmt.Errorf("%d/%d linters finished: deadline exceeded: try increase it by passing --deadline option",
finishedN, len(linters))