github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/result/processors/max_same_issues.go (about)

     1  package processors
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/vanstinator/golangci-lint/pkg/config"
     7  	"github.com/vanstinator/golangci-lint/pkg/logutils"
     8  	"github.com/vanstinator/golangci-lint/pkg/result"
     9  )
    10  
    11  type textToCountMap map[string]int
    12  
    13  type MaxSameIssues struct {
    14  	tc    textToCountMap
    15  	limit int
    16  	log   logutils.Log
    17  	cfg   *config.Config
    18  }
    19  
    20  var _ Processor = &MaxSameIssues{}
    21  
    22  func NewMaxSameIssues(limit int, log logutils.Log, cfg *config.Config) *MaxSameIssues {
    23  	return &MaxSameIssues{
    24  		tc:    textToCountMap{},
    25  		limit: limit,
    26  		log:   log,
    27  		cfg:   cfg,
    28  	}
    29  }
    30  
    31  func (p *MaxSameIssues) Name() string {
    32  	return "max_same_issues"
    33  }
    34  
    35  func (p *MaxSameIssues) Process(issues []result.Issue) ([]result.Issue, error) {
    36  	if p.limit <= 0 { // no limit
    37  		return issues, nil
    38  	}
    39  
    40  	return filterIssues(issues, func(i *result.Issue) bool {
    41  		if i.Replacement != nil && p.cfg.Issues.NeedFix {
    42  			// we need to fix all issues at once => we need to return all of them
    43  			return true
    44  		}
    45  
    46  		p.tc[i.Text]++ // always inc for stat
    47  		return p.tc[i.Text] <= p.limit
    48  	}), nil
    49  }
    50  
    51  func (p *MaxSameIssues) Finish() {
    52  	walkStringToIntMapSortedByValue(p.tc, func(text string, count int) {
    53  		if count > p.limit {
    54  			p.log.Infof("%d/%d issues with text %q were hidden, use --max-same-issues",
    55  				count-p.limit, count, text)
    56  		}
    57  	})
    58  }
    59  
    60  type kv struct {
    61  	Key   string
    62  	Value int
    63  }
    64  
    65  func walkStringToIntMapSortedByValue(m map[string]int, walk func(k string, v int)) {
    66  	var ss []kv
    67  	for k, v := range m {
    68  		ss = append(ss, kv{
    69  			Key:   k,
    70  			Value: v,
    71  		})
    72  	}
    73  
    74  	sort.Slice(ss, func(i, j int) bool {
    75  		return ss[i].Value > ss[j].Value
    76  	})
    77  
    78  	for _, kv := range ss {
    79  		walk(kv.Key, kv.Value)
    80  	}
    81  }