150 lines
4.1 KiB
Go
150 lines
4.1 KiB
Go
package lintersdb
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/golangci/golangci-lint/pkg/config"
|
|
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
|
)
|
|
|
|
type EnabledSet struct {
|
|
m *Manager
|
|
v *Validator
|
|
log logutils.Log
|
|
cfg *config.Config
|
|
}
|
|
|
|
func NewEnabledSet(m *Manager, v *Validator, log logutils.Log, cfg *config.Config) *EnabledSet {
|
|
return &EnabledSet{
|
|
m: m,
|
|
v: v,
|
|
log: log,
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
// nolint:gocyclo
|
|
func (es EnabledSet) build(lcfg *config.Linters, enabledByDefaultLinters []*linter.Config) map[string]*linter.Config {
|
|
resultLintersSet := map[string]*linter.Config{}
|
|
switch {
|
|
case len(lcfg.Presets) != 0:
|
|
break // imply --disable-all
|
|
case lcfg.EnableAll:
|
|
resultLintersSet = linterConfigsToMap(es.m.GetAllSupportedLinterConfigs())
|
|
case lcfg.DisableAll:
|
|
break
|
|
default:
|
|
resultLintersSet = linterConfigsToMap(enabledByDefaultLinters)
|
|
}
|
|
|
|
// --presets can only add linters to default set
|
|
for _, p := range lcfg.Presets {
|
|
for _, lc := range es.m.GetAllLinterConfigsForPreset(p) {
|
|
lc := lc
|
|
resultLintersSet[lc.Name()] = lc
|
|
}
|
|
}
|
|
|
|
// --fast removes slow linters from current set.
|
|
// It should be after --presets to be able to run only fast linters in preset.
|
|
// It should be before --enable and --disable to be able to enable or disable specific linter.
|
|
if lcfg.Fast {
|
|
for name := range resultLintersSet {
|
|
if es.m.GetLinterConfig(name).NeedsSSARepr {
|
|
delete(resultLintersSet, name)
|
|
}
|
|
}
|
|
}
|
|
|
|
metaLinters := es.m.GetMetaLinters()
|
|
|
|
for _, name := range lcfg.Enable {
|
|
if metaLinter := metaLinters[name]; metaLinter != nil {
|
|
// e.g. if we use --enable=megacheck we should add staticcheck,unused and gosimple to result set
|
|
for _, childLinter := range metaLinter.DefaultChildLinterNames() {
|
|
resultLintersSet[childLinter] = es.m.GetLinterConfig(childLinter)
|
|
}
|
|
continue
|
|
}
|
|
|
|
lc := es.m.GetLinterConfig(name)
|
|
// it's important to use lc.Name() nor name because name can be alias
|
|
resultLintersSet[lc.Name()] = lc
|
|
}
|
|
|
|
for _, name := range lcfg.Disable {
|
|
if metaLinter := metaLinters[name]; metaLinter != nil {
|
|
// e.g. if we use --disable=megacheck we should remove staticcheck,unused and gosimple from result set
|
|
for _, childLinter := range metaLinter.DefaultChildLinterNames() {
|
|
delete(resultLintersSet, childLinter)
|
|
}
|
|
continue
|
|
}
|
|
|
|
lc := es.m.GetLinterConfig(name)
|
|
// it's important to use lc.Name() nor name because name can be alias
|
|
delete(resultLintersSet, lc.Name())
|
|
}
|
|
|
|
return resultLintersSet
|
|
}
|
|
|
|
func (es EnabledSet) optimizeLintersSet(linters map[string]*linter.Config) {
|
|
for _, metaLinter := range es.m.GetMetaLinters() {
|
|
var children []string
|
|
for _, child := range metaLinter.AllChildLinterNames() {
|
|
if _, ok := linters[child]; ok {
|
|
children = append(children, child)
|
|
}
|
|
}
|
|
|
|
if len(children) <= 1 {
|
|
continue
|
|
}
|
|
|
|
for _, child := range children {
|
|
delete(linters, child)
|
|
}
|
|
builtLinterConfig, err := metaLinter.BuildLinterConfig(children)
|
|
if err != nil {
|
|
panic("shouldn't fail during linter building: " + err.Error())
|
|
}
|
|
linters[metaLinter.Name()] = builtLinterConfig
|
|
es.log.Infof("Optimized sublinters %s into metalinter %s", children, metaLinter.Name())
|
|
}
|
|
}
|
|
|
|
func (es EnabledSet) Get(optimize bool) ([]*linter.Config, error) {
|
|
if err := es.v.validateEnabledDisabledLintersConfig(&es.cfg.Linters); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resultLintersSet := es.build(&es.cfg.Linters, es.m.GetAllEnabledByDefaultLinters())
|
|
es.verbosePrintLintersStatus(resultLintersSet)
|
|
if optimize {
|
|
es.optimizeLintersSet(resultLintersSet)
|
|
}
|
|
|
|
var resultLinters []*linter.Config
|
|
for _, lc := range resultLintersSet {
|
|
resultLinters = append(resultLinters, lc)
|
|
}
|
|
|
|
return resultLinters, nil
|
|
}
|
|
|
|
func (es EnabledSet) verbosePrintLintersStatus(lcs map[string]*linter.Config) {
|
|
var linterNames []string
|
|
for _, lc := range lcs {
|
|
linterNames = append(linterNames, lc.Name())
|
|
}
|
|
sort.StringSlice(linterNames).Sort()
|
|
es.log.Infof("Active %d linters: %s", len(linterNames), linterNames)
|
|
|
|
if len(es.cfg.Linters.Presets) != 0 {
|
|
sort.StringSlice(es.cfg.Linters.Presets).Sort()
|
|
es.log.Infof("Active presets: %s", es.cfg.Linters.Presets)
|
|
}
|
|
}
|