package lintersdb import ( "sort" "github.com/golangci/golangci-lint/pkg/config" "github.com/golangci/golangci-lint/pkg/golinters" "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).DoesFullImport { delete(resultLintersSet, name) } } } for _, name := range lcfg.Enable { 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 name == "megacheck" { for _, ln := range getAllMegacheckSubLinterNames() { delete(resultLintersSet, ln) } } lc := es.m.GetLinterConfig(name) // it's important to use lc.Name() nor name because name can be alias delete(resultLintersSet, lc.Name()) } es.optimizeLintersSet(resultLintersSet) return resultLintersSet } func getAllMegacheckSubLinterNames() []string { unusedName := golinters.Megacheck{UnusedEnabled: true}.Name() gosimpleName := golinters.Megacheck{GosimpleEnabled: true}.Name() staticcheckName := golinters.Megacheck{StaticcheckEnabled: true}.Name() return []string{unusedName, gosimpleName, staticcheckName} } func (es EnabledSet) optimizeLintersSet(linters map[string]*linter.Config) { unusedName := golinters.Megacheck{UnusedEnabled: true}.Name() gosimpleName := golinters.Megacheck{GosimpleEnabled: true}.Name() staticcheckName := golinters.Megacheck{StaticcheckEnabled: true}.Name() fullName := golinters.Megacheck{GosimpleEnabled: true, UnusedEnabled: true, StaticcheckEnabled: true}.Name() allNames := []string{unusedName, gosimpleName, staticcheckName, fullName} megacheckCount := 0 for _, n := range allNames { if linters[n] != nil { megacheckCount++ } } if megacheckCount <= 1 { return } isFullEnabled := linters[fullName] != nil mega := golinters.Megacheck{ UnusedEnabled: isFullEnabled || linters[unusedName] != nil, GosimpleEnabled: isFullEnabled || linters[gosimpleName] != nil, StaticcheckEnabled: isFullEnabled || linters[staticcheckName] != nil, } for _, n := range allNames { delete(linters, n) } lc := *es.m.GetLinterConfig("megacheck") lc.Linter = mega linters[mega.Name()] = &lc } func (es EnabledSet) Get() ([]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()) var resultLinters []linter.Config for _, lc := range resultLintersSet { resultLinters = append(resultLinters, *lc) } es.verbosePrintLintersStatus(resultLinters) return resultLinters, nil } func (es EnabledSet) verbosePrintLintersStatus(lcs []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) } }