github.com/thrasher-corp/golangci-lint@v1.17.3/pkg/lint/lintersdb/enabled_set.go (about) 1 package lintersdb 2 3 import ( 4 "sort" 5 6 "github.com/golangci/golangci-lint/pkg/config" 7 "github.com/golangci/golangci-lint/pkg/lint/linter" 8 "github.com/golangci/golangci-lint/pkg/logutils" 9 ) 10 11 type EnabledSet struct { 12 m *Manager 13 v *Validator 14 log logutils.Log 15 cfg *config.Config 16 } 17 18 func NewEnabledSet(m *Manager, v *Validator, log logutils.Log, cfg *config.Config) *EnabledSet { 19 return &EnabledSet{ 20 m: m, 21 v: v, 22 log: log, 23 cfg: cfg, 24 } 25 } 26 27 // nolint:gocyclo 28 func (es EnabledSet) build(lcfg *config.Linters, enabledByDefaultLinters []*linter.Config) map[string]*linter.Config { 29 resultLintersSet := map[string]*linter.Config{} 30 switch { 31 case len(lcfg.Presets) != 0: 32 break // imply --disable-all 33 case lcfg.EnableAll: 34 resultLintersSet = linterConfigsToMap(es.m.GetAllSupportedLinterConfigs()) 35 case lcfg.DisableAll: 36 break 37 default: 38 resultLintersSet = linterConfigsToMap(enabledByDefaultLinters) 39 } 40 41 // --presets can only add linters to default set 42 for _, p := range lcfg.Presets { 43 for _, lc := range es.m.GetAllLinterConfigsForPreset(p) { 44 lc := lc 45 resultLintersSet[lc.Name()] = lc 46 } 47 } 48 49 // --fast removes slow linters from current set. 50 // It should be after --presets to be able to run only fast linters in preset. 51 // It should be before --enable and --disable to be able to enable or disable specific linter. 52 if lcfg.Fast { 53 for name := range resultLintersSet { 54 if es.m.GetLinterConfig(name).NeedsSSARepr { 55 delete(resultLintersSet, name) 56 } 57 } 58 } 59 60 metaLinters := es.m.GetMetaLinters() 61 62 for _, name := range lcfg.Enable { 63 if metaLinter := metaLinters[name]; metaLinter != nil { 64 // e.g. if we use --enable=megacheck we should add staticcheck,unused and gosimple to result set 65 for _, childLinter := range metaLinter.DefaultChildLinterNames() { 66 resultLintersSet[childLinter] = es.m.GetLinterConfig(childLinter) 67 } 68 continue 69 } 70 71 lc := es.m.GetLinterConfig(name) 72 // it's important to use lc.Name() nor name because name can be alias 73 resultLintersSet[lc.Name()] = lc 74 } 75 76 for _, name := range lcfg.Disable { 77 if metaLinter := metaLinters[name]; metaLinter != nil { 78 // e.g. if we use --disable=megacheck we should remove staticcheck,unused and gosimple from result set 79 for _, childLinter := range metaLinter.DefaultChildLinterNames() { 80 delete(resultLintersSet, childLinter) 81 } 82 continue 83 } 84 85 lc := es.m.GetLinterConfig(name) 86 // it's important to use lc.Name() nor name because name can be alias 87 delete(resultLintersSet, lc.Name()) 88 } 89 90 return resultLintersSet 91 } 92 93 func (es EnabledSet) optimizeLintersSet(linters map[string]*linter.Config) { 94 for _, metaLinter := range es.m.GetMetaLinters() { 95 var children []string 96 for _, child := range metaLinter.AllChildLinterNames() { 97 if _, ok := linters[child]; ok { 98 children = append(children, child) 99 } 100 } 101 102 if len(children) <= 1 { 103 continue 104 } 105 106 for _, child := range children { 107 delete(linters, child) 108 } 109 builtLinterConfig, err := metaLinter.BuildLinterConfig(children) 110 if err != nil { 111 panic("shouldn't fail during linter building: " + err.Error()) 112 } 113 linters[metaLinter.Name()] = builtLinterConfig 114 es.log.Infof("Optimized sublinters %s into metalinter %s", children, metaLinter.Name()) 115 } 116 } 117 118 func (es EnabledSet) Get(optimize bool) ([]*linter.Config, error) { 119 if err := es.v.validateEnabledDisabledLintersConfig(&es.cfg.Linters); err != nil { 120 return nil, err 121 } 122 123 resultLintersSet := es.build(&es.cfg.Linters, es.m.GetAllEnabledByDefaultLinters()) 124 es.verbosePrintLintersStatus(resultLintersSet) 125 if optimize { 126 es.optimizeLintersSet(resultLintersSet) 127 } 128 129 var resultLinters []*linter.Config 130 for _, lc := range resultLintersSet { 131 resultLinters = append(resultLinters, lc) 132 } 133 134 return resultLinters, nil 135 } 136 137 func (es EnabledSet) verbosePrintLintersStatus(lcs map[string]*linter.Config) { 138 var linterNames []string 139 for _, lc := range lcs { 140 linterNames = append(linterNames, lc.Name()) 141 } 142 sort.StringSlice(linterNames).Sort() 143 es.log.Infof("Active %d linters: %s", len(linterNames), linterNames) 144 145 if len(es.cfg.Linters.Presets) != 0 { 146 sort.StringSlice(es.cfg.Linters.Presets).Sort() 147 es.log.Infof("Active presets: %s", es.cfg.Linters.Presets) 148 } 149 }