1package lintersdb
2
3import (
4	"fmt"
5	"path/filepath"
6	"plugin"
7
8	"github.com/spf13/viper"
9	"golang.org/x/tools/go/analysis"
10
11	"github.com/golangci/golangci-lint/pkg/config"
12	"github.com/golangci/golangci-lint/pkg/golinters"
13	"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
14	"github.com/golangci/golangci-lint/pkg/lint/linter"
15	"github.com/golangci/golangci-lint/pkg/logutils"
16	"github.com/golangci/golangci-lint/pkg/report"
17)
18
19type Manager struct {
20	nameToLCs map[string][]*linter.Config
21	cfg       *config.Config
22	log       logutils.Log
23}
24
25func NewManager(cfg *config.Config, log logutils.Log) *Manager {
26	m := &Manager{cfg: cfg, log: log}
27	nameToLCs := make(map[string][]*linter.Config)
28	for _, lc := range m.GetAllSupportedLinterConfigs() {
29		for _, name := range lc.AllNames() {
30			nameToLCs[name] = append(nameToLCs[name], lc)
31		}
32	}
33
34	m.nameToLCs = nameToLCs
35	return m
36}
37
38func (m *Manager) WithCustomLinters() *Manager {
39	if m.log == nil {
40		m.log = report.NewLogWrapper(logutils.NewStderrLog(""), &report.Data{})
41	}
42	if m.cfg != nil {
43		for name, settings := range m.cfg.LintersSettings.Custom {
44			lc, err := m.loadCustomLinterConfig(name, settings)
45
46			if err != nil {
47				m.log.Errorf("Unable to load custom analyzer %s:%s, %v",
48					name,
49					settings.Path,
50					err)
51			} else {
52				m.nameToLCs[name] = append(m.nameToLCs[name], lc)
53			}
54		}
55	}
56	return m
57}
58
59func (Manager) AllPresets() []string {
60	return []string{
61		linter.PresetBugs,
62		linter.PresetComment,
63		linter.PresetComplexity,
64		linter.PresetError,
65		linter.PresetFormatting,
66		linter.PresetImport,
67		linter.PresetMetaLinter,
68		linter.PresetModule,
69		linter.PresetPerformance,
70		linter.PresetSQL,
71		linter.PresetStyle,
72		linter.PresetTest,
73		linter.PresetUnused,
74	}
75}
76
77func (m Manager) allPresetsSet() map[string]bool {
78	ret := map[string]bool{}
79	for _, p := range m.AllPresets() {
80		ret[p] = true
81	}
82	return ret
83}
84
85func (m Manager) GetLinterConfigs(name string) []*linter.Config {
86	return m.nameToLCs[name]
87}
88
89func enableLinterConfigs(lcs []*linter.Config, isEnabled func(lc *linter.Config) bool) []*linter.Config {
90	var ret []*linter.Config
91	for _, lc := range lcs {
92		lc := lc
93		lc.EnabledByDefault = isEnabled(lc)
94		ret = append(ret, lc)
95	}
96
97	return ret
98}
99
100//nolint:funlen
101func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
102	var govetCfg *config.GovetSettings
103	var testpackageCfg *config.TestpackageSettings
104	var exhaustiveCfg *config.ExhaustiveSettings
105	var exhaustiveStructCfg *config.ExhaustiveStructSettings
106	var errorlintCfg *config.ErrorLintSettings
107	var thelperCfg *config.ThelperSettings
108	var predeclaredCfg *config.PredeclaredSettings
109	var ifshortCfg *config.IfshortSettings
110	var reviveCfg *config.ReviveSettings
111	var cyclopCfg *config.Cyclop
112	var importAsCfg *config.ImportAsSettings
113	var goModDirectivesCfg *config.GoModDirectivesSettings
114	var tagliatelleCfg *config.TagliatelleSettings
115	var gosecCfg *config.GoSecSettings
116	var gosimpleCfg *config.StaticCheckSettings
117	var staticcheckCfg *config.StaticCheckSettings
118	var stylecheckCfg *config.StaticCheckSettings
119	var unusedCfg *config.StaticCheckSettings
120	var wrapcheckCfg *config.WrapcheckSettings
121
122	if m.cfg != nil {
123		govetCfg = &m.cfg.LintersSettings.Govet
124		testpackageCfg = &m.cfg.LintersSettings.Testpackage
125		exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
126		exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
127		errorlintCfg = &m.cfg.LintersSettings.ErrorLint
128		thelperCfg = &m.cfg.LintersSettings.Thelper
129		predeclaredCfg = &m.cfg.LintersSettings.Predeclared
130		ifshortCfg = &m.cfg.LintersSettings.Ifshort
131		reviveCfg = &m.cfg.LintersSettings.Revive
132		cyclopCfg = &m.cfg.LintersSettings.Cyclop
133		importAsCfg = &m.cfg.LintersSettings.ImportAs
134		goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
135		tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
136		gosecCfg = &m.cfg.LintersSettings.Gosec
137		gosimpleCfg = &m.cfg.LintersSettings.Gosimple
138		staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
139		stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
140		unusedCfg = &m.cfg.LintersSettings.Unused
141		wrapcheckCfg = &m.cfg.LintersSettings.Wrapcheck
142	}
143
144	const megacheckName = "megacheck"
145
146	lcs := []*linter.Config{
147		linter.NewConfig(golinters.NewGovet(govetCfg)).
148			WithSince("v1.0.0").
149			WithLoadForGoAnalysis().
150			WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
151			WithAlternativeNames("vet", "vetshadow").
152			WithURL("https://golang.org/cmd/vet/"),
153		linter.NewConfig(golinters.NewBodyclose()).
154			WithSince("v1.18.0").
155			WithLoadForGoAnalysis().
156			WithPresets(linter.PresetPerformance, linter.PresetBugs).
157			WithURL("https://github.com/timakin/bodyclose"),
158		linter.NewConfig(golinters.NewNoctx()).
159			WithSince("v1.28.0").
160			WithLoadForGoAnalysis().
161			WithPresets(linter.PresetPerformance, linter.PresetBugs).
162			WithURL("https://github.com/sonatard/noctx"),
163		linter.NewConfig(golinters.NewErrcheck()).
164			WithSince("v1.0.0").
165			WithLoadForGoAnalysis().
166			WithPresets(linter.PresetBugs, linter.PresetError).
167			WithURL("https://github.com/kisielk/errcheck"),
168		linter.NewConfig(golinters.NewGolint()).
169			WithSince("v1.0.0").
170			WithLoadForGoAnalysis().
171			WithPresets(linter.PresetStyle).
172			WithURL("https://github.com/golang/lint").
173			Deprecated("The repository of the linter has been archived by the owner.", "v1.41.0", "revive"),
174		linter.NewConfig(golinters.NewRowsErrCheck()).
175			WithSince("v1.23.0").
176			WithLoadForGoAnalysis().
177			WithPresets(linter.PresetBugs, linter.PresetSQL).
178			WithURL("https://github.com/jingyugao/rowserrcheck"),
179
180		linter.NewConfig(golinters.NewStaticcheck(staticcheckCfg)).
181			WithSince("v1.0.0").
182			WithLoadForGoAnalysis().
183			WithPresets(linter.PresetBugs, linter.PresetMetaLinter).
184			WithAlternativeNames(megacheckName).
185			WithURL("https://staticcheck.io/"),
186		linter.NewConfig(golinters.NewUnused(unusedCfg)).
187			WithSince("v1.20.0").
188			WithLoadForGoAnalysis().
189			WithPresets(linter.PresetUnused).
190			WithAlternativeNames(megacheckName).
191			ConsiderSlow().
192			WithChangeTypes().
193			WithURL("https://github.com/dominikh/go-tools/tree/master/unused"),
194		linter.NewConfig(golinters.NewGosimple(gosimpleCfg)).
195			WithSince("v1.20.0").
196			WithLoadForGoAnalysis().
197			WithPresets(linter.PresetStyle).
198			WithAlternativeNames(megacheckName).
199			WithURL("https://github.com/dominikh/go-tools/tree/master/simple"),
200
201		linter.NewConfig(golinters.NewStylecheck(stylecheckCfg)).
202			WithSince("v1.20.0").
203			WithLoadForGoAnalysis().
204			WithPresets(linter.PresetStyle).
205			WithURL("https://github.com/dominikh/go-tools/tree/master/stylecheck"),
206		linter.NewConfig(golinters.NewGosec(gosecCfg)).
207			WithSince("v1.0.0").
208			WithLoadForGoAnalysis().
209			WithPresets(linter.PresetBugs).
210			WithURL("https://github.com/securego/gosec").
211			WithAlternativeNames("gas"),
212		linter.NewConfig(golinters.NewStructcheck()).
213			WithSince("v1.0.0").
214			WithLoadForGoAnalysis().
215			WithPresets(linter.PresetUnused).
216			WithURL("https://github.com/opennota/check"),
217		linter.NewConfig(golinters.NewVarcheck()).
218			WithSince("v1.0.0").
219			WithLoadForGoAnalysis().
220			WithPresets(linter.PresetUnused).
221			WithURL("https://github.com/opennota/check"),
222		linter.NewConfig(golinters.NewInterfacer()).
223			WithSince("v1.0.0").
224			WithLoadForGoAnalysis().
225			WithPresets(linter.PresetStyle).
226			WithURL("https://github.com/mvdan/interfacer").
227			Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
228		linter.NewConfig(golinters.NewUnconvert()).
229			WithSince("v1.0.0").
230			WithLoadForGoAnalysis().
231			WithPresets(linter.PresetStyle).
232			WithURL("https://github.com/mdempsky/unconvert"),
233		linter.NewConfig(golinters.NewIneffassign()).
234			WithSince("v1.0.0").
235			WithPresets(linter.PresetUnused).
236			WithURL("https://github.com/gordonklaus/ineffassign"),
237		linter.NewConfig(golinters.NewDupl()).
238			WithSince("v1.0.0").
239			WithPresets(linter.PresetStyle).
240			WithURL("https://github.com/mibk/dupl"),
241		linter.NewConfig(golinters.NewGoconst()).
242			WithSince("v1.0.0").
243			WithPresets(linter.PresetStyle).
244			WithURL("https://github.com/jgautheron/goconst"),
245		linter.NewConfig(golinters.NewDeadcode()).
246			WithSince("v1.0.0").
247			WithLoadForGoAnalysis().
248			WithPresets(linter.PresetUnused).
249			WithURL("https://github.com/remyoudompheng/go-misc/tree/master/deadcode"),
250		linter.NewConfig(golinters.NewGocyclo()).
251			WithSince("v1.0.0").
252			WithPresets(linter.PresetComplexity).
253			WithURL("https://github.com/fzipp/gocyclo"),
254		linter.NewConfig(golinters.NewCyclop(cyclopCfg)).
255			WithSince("v1.37.0").
256			WithLoadForGoAnalysis().
257			WithPresets(linter.PresetComplexity).
258			WithURL("https://github.com/bkielbasa/cyclop"),
259		linter.NewConfig(golinters.NewGocognit()).
260			WithSince("v1.20.0").
261			WithPresets(linter.PresetComplexity).
262			WithURL("https://github.com/uudashr/gocognit"),
263		linter.NewConfig(golinters.NewTypecheck()).
264			WithSince("v1.3.0").
265			WithLoadForGoAnalysis().
266			WithPresets(linter.PresetBugs).
267			WithURL(""),
268		linter.NewConfig(golinters.NewAsciicheck()).
269			WithSince("v1.26.0").
270			WithPresets(linter.PresetBugs, linter.PresetStyle).
271			WithURL("https://github.com/tdakkota/asciicheck"),
272
273		linter.NewConfig(golinters.NewGofmt()).
274			WithSince("v1.0.0").
275			WithPresets(linter.PresetFormatting).
276			WithAutoFix().
277			WithURL("https://golang.org/cmd/gofmt/"),
278		linter.NewConfig(golinters.NewGofumpt()).
279			WithSince("v1.28.0").
280			WithPresets(linter.PresetFormatting).
281			WithAutoFix().
282			WithURL("https://github.com/mvdan/gofumpt"),
283		linter.NewConfig(golinters.NewGoimports()).
284			WithSince("v1.20.0").
285			WithPresets(linter.PresetFormatting, linter.PresetImport).
286			WithAutoFix().
287			WithURL("https://godoc.org/golang.org/x/tools/cmd/goimports"),
288		linter.NewConfig(golinters.NewGoHeader()).
289			WithSince("v1.28.0").
290			WithPresets(linter.PresetStyle).
291			WithURL("https://github.com/denis-tingajkin/go-header"),
292		linter.NewConfig(golinters.NewGci()).
293			WithSince("v1.30.0").
294			WithPresets(linter.PresetFormatting, linter.PresetImport).
295			WithAutoFix().
296			WithURL("https://github.com/daixiang0/gci"),
297		linter.NewConfig(golinters.NewMaligned()).
298			WithSince("v1.0.0").
299			WithLoadForGoAnalysis().
300			WithPresets(linter.PresetPerformance).
301			WithURL("https://github.com/mdempsky/maligned").
302			Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"),
303		linter.NewConfig(golinters.NewDepguard()).
304			WithSince("v1.4.0").
305			WithLoadForGoAnalysis().
306			WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule).
307			WithURL("https://github.com/OpenPeeDeeP/depguard"),
308		linter.NewConfig(golinters.NewMisspell()).
309			WithSince("v1.8.0").
310			WithPresets(linter.PresetStyle, linter.PresetComment).
311			WithAutoFix().
312			WithURL("https://github.com/client9/misspell"),
313		linter.NewConfig(golinters.NewLLL()).
314			WithSince("v1.8.0").
315			WithPresets(linter.PresetStyle),
316		linter.NewConfig(golinters.NewUnparam()).
317			WithSince("v1.9.0").
318			WithPresets(linter.PresetUnused).
319			WithLoadForGoAnalysis().
320			WithURL("https://github.com/mvdan/unparam"),
321		linter.NewConfig(golinters.NewDogsled()).
322			WithSince("v1.19.0").
323			WithPresets(linter.PresetStyle).
324			WithURL("https://github.com/alexkohler/dogsled"),
325		linter.NewConfig(golinters.NewNakedret()).
326			WithSince("v1.19.0").
327			WithPresets(linter.PresetStyle).
328			WithURL("https://github.com/alexkohler/nakedret"),
329		linter.NewConfig(golinters.NewPrealloc()).
330			WithSince("v1.19.0").
331			WithPresets(linter.PresetPerformance).
332			WithURL("https://github.com/alexkohler/prealloc"),
333		linter.NewConfig(golinters.NewScopelint()).
334			WithSince("v1.12.0").
335			WithPresets(linter.PresetBugs).
336			WithURL("https://github.com/kyoh86/scopelint").
337			Deprecated("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"),
338		linter.NewConfig(golinters.NewGocritic()).
339			WithSince("v1.12.0").
340			WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
341			WithLoadForGoAnalysis().
342			WithURL("https://github.com/go-critic/go-critic"),
343		linter.NewConfig(golinters.NewGochecknoinits()).
344			WithSince("v1.12.0").
345			WithPresets(linter.PresetStyle).
346			WithURL("https://github.com/leighmcculloch/gochecknoinits"),
347		linter.NewConfig(golinters.NewGochecknoglobals()).
348			WithSince("v1.12.0").
349			WithPresets(linter.PresetStyle).
350			WithURL("https://github.com/leighmcculloch/gochecknoglobals"),
351		linter.NewConfig(golinters.NewGodox()).
352			WithSince("v1.19.0").
353			WithPresets(linter.PresetStyle, linter.PresetComment).
354			WithURL("https://github.com/matoous/godox"),
355		linter.NewConfig(golinters.NewFunlen()).
356			WithSince("v1.18.0").
357			WithPresets(linter.PresetComplexity).
358			WithURL("https://github.com/ultraware/funlen"),
359		linter.NewConfig(golinters.NewWhitespace()).
360			WithSince("v1.19.0").
361			WithPresets(linter.PresetStyle).
362			WithAutoFix().
363			WithURL("https://github.com/ultraware/whitespace"),
364		linter.NewConfig(golinters.NewWSL()).
365			WithSince("v1.20.0").
366			WithPresets(linter.PresetStyle).
367			WithURL("https://github.com/bombsimon/wsl"),
368		linter.NewConfig(golinters.NewGoPrintfFuncName()).
369			WithSince("v1.23.0").
370			WithPresets(linter.PresetStyle).
371			WithURL("https://github.com/jirfag/go-printf-func-name"),
372		linter.NewConfig(golinters.NewGoMND(m.cfg)).
373			WithSince("v1.22.0").
374			WithPresets(linter.PresetStyle).
375			WithURL("https://github.com/tommy-muehle/go-mnd"),
376		linter.NewConfig(golinters.NewGoerr113()).
377			WithSince("v1.26.0").
378			WithPresets(linter.PresetStyle, linter.PresetError).
379			WithLoadForGoAnalysis().
380			WithURL("https://github.com/Djarvur/go-err113"),
381		linter.NewConfig(golinters.NewGomodguard()).
382			WithSince("v1.25.0").
383			WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule).
384			WithURL("https://github.com/ryancurrah/gomodguard"),
385		linter.NewConfig(golinters.NewGodot()).
386			WithSince("v1.25.0").
387			WithPresets(linter.PresetStyle, linter.PresetComment).
388			WithAutoFix().
389			WithURL("https://github.com/tetafro/godot"),
390		linter.NewConfig(golinters.NewTestpackage(testpackageCfg)).
391			WithSince("v1.25.0").
392			WithPresets(linter.PresetStyle, linter.PresetTest).
393			WithURL("https://github.com/maratori/testpackage"),
394		linter.NewConfig(golinters.NewNestif()).
395			WithSince("v1.25.0").
396			WithPresets(linter.PresetComplexity).
397			WithURL("https://github.com/nakabonne/nestif"),
398		linter.NewConfig(golinters.NewExportLoopRef()).
399			WithSince("v1.28.0").
400			WithPresets(linter.PresetBugs).
401			WithLoadForGoAnalysis().
402			WithURL("https://github.com/kyoh86/exportloopref"),
403		linter.NewConfig(golinters.NewExhaustive(exhaustiveCfg)).
404			WithSince(" v1.28.0").
405			WithPresets(linter.PresetBugs).
406			WithLoadForGoAnalysis().
407			WithURL("https://github.com/nishanths/exhaustive"),
408		linter.NewConfig(golinters.NewSQLCloseCheck()).
409			WithSince("v1.28.0").
410			WithPresets(linter.PresetBugs, linter.PresetSQL).
411			WithLoadForGoAnalysis().
412			WithURL("https://github.com/ryanrolds/sqlclosecheck"),
413		linter.NewConfig(golinters.NewNLReturn()).
414			WithSince("v1.30.0").
415			WithPresets(linter.PresetStyle).
416			WithURL("https://github.com/ssgreg/nlreturn"),
417		linter.NewConfig(golinters.NewWrapcheck(wrapcheckCfg)).
418			WithSince("v1.32.0").
419			WithPresets(linter.PresetStyle, linter.PresetError).
420			WithLoadForGoAnalysis().
421			WithURL("https://github.com/tomarrell/wrapcheck"),
422		linter.NewConfig(golinters.NewThelper(thelperCfg)).
423			WithSince("v1.34.0").
424			WithPresets(linter.PresetStyle).
425			WithLoadForGoAnalysis().
426			WithURL("https://github.com/kulti/thelper"),
427		linter.NewConfig(golinters.NewTparallel()).
428			WithSince("v1.32.0").
429			WithPresets(linter.PresetStyle, linter.PresetTest).
430			WithLoadForGoAnalysis().
431			WithURL("https://github.com/moricho/tparallel"),
432		linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)).
433			WithSince("v1.32.0").
434			WithPresets(linter.PresetStyle, linter.PresetTest).
435			WithLoadForGoAnalysis().
436			WithURL("https://github.com/mbilski/exhaustivestruct"),
437		linter.NewConfig(golinters.NewErrorLint(errorlintCfg)).
438			WithSince("v1.32.0").
439			WithPresets(linter.PresetBugs, linter.PresetError).
440			WithLoadForGoAnalysis().
441			WithURL("https://github.com/polyfloyd/go-errorlint"),
442		linter.NewConfig(golinters.NewParallelTest()).
443			WithSince("v1.33.0").
444			WithPresets(linter.PresetStyle, linter.PresetTest).
445			WithURL("https://github.com/kunwardeep/paralleltest"),
446		linter.NewConfig(golinters.NewMakezero()).
447			WithSince("v1.34.0").
448			WithPresets(linter.PresetStyle, linter.PresetBugs).
449			WithLoadForGoAnalysis().
450			WithURL("https://github.com/ashanbrown/makezero"),
451		linter.NewConfig(golinters.NewForbidigo()).
452			WithSince("v1.34.0").
453			WithPresets(linter.PresetStyle).
454			WithURL("https://github.com/ashanbrown/forbidigo"),
455		linter.NewConfig(golinters.NewIfshort(ifshortCfg)).
456			WithSince("v1.36.0").
457			WithPresets(linter.PresetStyle).
458			WithURL("https://github.com/esimonov/ifshort"),
459		linter.NewConfig(golinters.NewPredeclared(predeclaredCfg)).
460			WithSince("v1.35.0").
461			WithPresets(linter.PresetStyle).
462			WithURL("https://github.com/nishanths/predeclared"),
463		linter.NewConfig(golinters.NewRevive(reviveCfg)).
464			WithSince("v1.37.0").
465			WithPresets(linter.PresetStyle, linter.PresetMetaLinter).
466			ConsiderSlow().
467			WithURL("https://github.com/mgechev/revive"),
468		linter.NewConfig(golinters.NewDurationCheck()).
469			WithSince("v1.37.0").
470			WithPresets(linter.PresetBugs).
471			WithLoadForGoAnalysis().
472			WithURL("https://github.com/charithe/durationcheck"),
473		linter.NewConfig(golinters.NewWastedAssign()).
474			WithSince("v1.38.0").
475			WithPresets(linter.PresetStyle).
476			WithLoadForGoAnalysis().
477			WithURL("https://github.com/sanposhiho/wastedassign"),
478		linter.NewConfig(golinters.NewImportAs(importAsCfg)).
479			WithSince("v1.38.0").
480			WithPresets(linter.PresetStyle).
481			WithLoadForGoAnalysis().
482			WithURL("https://github.com/julz/importas"),
483		linter.NewConfig(golinters.NewNilErr()).
484			WithSince("v1.38.0").
485			WithLoadForGoAnalysis().
486			WithPresets(linter.PresetBugs).
487			WithURL("https://github.com/gostaticanalysis/nilerr"),
488		linter.NewConfig(golinters.NewForceTypeAssert()).
489			WithSince("v1.38.0").
490			WithPresets(linter.PresetStyle).
491			WithURL("https://github.com/gostaticanalysis/forcetypeassert"),
492		linter.NewConfig(golinters.NewGoModDirectives(goModDirectivesCfg)).
493			WithSince("v1.39.0").
494			WithPresets(linter.PresetStyle, linter.PresetModule).
495			WithURL("https://github.com/ldez/gomoddirectives"),
496		linter.NewConfig(golinters.NewPromlinter()).
497			WithSince("v1.40.0").
498			WithPresets(linter.PresetStyle).
499			WithURL("https://github.com/yeya24/promlinter"),
500		linter.NewConfig(golinters.NewTagliatelle(tagliatelleCfg)).
501			WithSince("v1.40.0").
502			WithPresets(linter.PresetStyle).
503			WithURL("https://github.com/ldez/tagliatelle"),
504
505		// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
506		linter.NewConfig(golinters.NewNoLintLint()).
507			WithSince("v1.26.0").
508			WithPresets(linter.PresetStyle).
509			WithURL("https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint/README.md"),
510	}
511
512	enabledByDefault := map[string]bool{
513		golinters.NewGovet(nil).Name():                  true,
514		golinters.NewErrcheck().Name():                  true,
515		golinters.NewStaticcheck(staticcheckCfg).Name(): true,
516		golinters.NewUnused(unusedCfg).Name():           true,
517		golinters.NewGosimple(gosimpleCfg).Name():       true,
518		golinters.NewStructcheck().Name():               true,
519		golinters.NewVarcheck().Name():                  true,
520		golinters.NewIneffassign().Name():               true,
521		golinters.NewDeadcode().Name():                  true,
522		golinters.NewTypecheck().Name():                 true,
523	}
524	return enableLinterConfigs(lcs, func(lc *linter.Config) bool {
525		return enabledByDefault[lc.Name()]
526	})
527}
528
529func (m Manager) GetAllEnabledByDefaultLinters() []*linter.Config {
530	var ret []*linter.Config
531	for _, lc := range m.GetAllSupportedLinterConfigs() {
532		if lc.EnabledByDefault {
533			ret = append(ret, lc)
534		}
535	}
536
537	return ret
538}
539
540func linterConfigsToMap(lcs []*linter.Config) map[string]*linter.Config {
541	ret := map[string]*linter.Config{}
542	for _, lc := range lcs {
543		lc := lc // local copy
544		ret[lc.Name()] = lc
545	}
546
547	return ret
548}
549
550func (m Manager) GetAllLinterConfigsForPreset(p string) []*linter.Config {
551	var ret []*linter.Config
552	for _, lc := range m.GetAllSupportedLinterConfigs() {
553		for _, ip := range lc.InPresets {
554			if p == ip {
555				ret = append(ret, lc)
556				break
557			}
558		}
559	}
560
561	return ret
562}
563
564func (m Manager) loadCustomLinterConfig(name string, settings config.CustomLinterSettings) (*linter.Config, error) {
565	analyzer, err := m.getAnalyzerPlugin(settings.Path)
566	if err != nil {
567		return nil, err
568	}
569	m.log.Infof("Loaded %s: %s", settings.Path, name)
570	customLinter := goanalysis.NewLinter(
571		name,
572		settings.Description,
573		analyzer.GetAnalyzers(),
574		nil).WithLoadMode(goanalysis.LoadModeTypesInfo)
575	linterConfig := linter.NewConfig(customLinter)
576	linterConfig.EnabledByDefault = true
577	linterConfig.IsSlow = false
578	linterConfig.WithURL(settings.OriginalURL)
579	return linterConfig, nil
580}
581
582type AnalyzerPlugin interface {
583	GetAnalyzers() []*analysis.Analyzer
584}
585
586func (m Manager) getAnalyzerPlugin(path string) (AnalyzerPlugin, error) {
587	if !filepath.IsAbs(path) {
588		// resolve non-absolute paths relative to config file's directory
589		configFilePath := viper.ConfigFileUsed()
590		absConfigFilePath, err := filepath.Abs(configFilePath)
591		if err != nil {
592			return nil, fmt.Errorf("could not get absolute representation of config file path %q: %v", configFilePath, err)
593		}
594		path = filepath.Join(filepath.Dir(absConfigFilePath), path)
595	}
596
597	plug, err := plugin.Open(path)
598	if err != nil {
599		return nil, err
600	}
601
602	symbol, err := plug.Lookup("AnalyzerPlugin")
603	if err != nil {
604		return nil, err
605	}
606
607	analyzerPlugin, ok := symbol.(AnalyzerPlugin)
608	if !ok {
609		return nil, fmt.Errorf("plugin %s does not abide by 'AnalyzerPlugin' interface", path)
610	}
611
612	return analyzerPlugin, nil
613}
614