From 4f8ea21eb0b46f774197c12372ead41082653a0c Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Tue, 16 Mar 2021 01:42:02 +0100 Subject: [PATCH 1/4] feat: add Since field to linter config --- pkg/lint/linter/config.go | 7 ++++ pkg/lint/lintersdb/manager.go | 79 ++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/pkg/lint/linter/config.go b/pkg/lint/linter/config.go index 3d741803dc6a..9f090a43ddd5 100644 --- a/pkg/lint/linter/config.go +++ b/pkg/lint/linter/config.go @@ -34,6 +34,8 @@ type Config struct { IsSlow bool DoesChangeTypes bool DeprecatedMessage string + + Since string } func (lc *Config) ConsiderSlow() *Config { @@ -82,6 +84,11 @@ func (lc *Config) WithChangeTypes() *Config { return lc } +func (lc *Config) WithSince(version string) *Config { + lc.Since = version + return lc +} + func (lc *Config) Deprecated(message string) *Config { lc.DeprecatedMessage = message return lc diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 55397eb59c87..c5437edfed90 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -112,6 +112,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { var cyclopCfg *config.Cyclop var importAsCfg *config.ImportAsSettings var goModDirectivesCfg *config.GoModDirectivesSettings + if m.cfg != nil { govetCfg = &m.cfg.LintersSettings.Govet testpackageCfg = &m.cfg.LintersSettings.Testpackage @@ -126,40 +127,50 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { importAsCfg = &m.cfg.LintersSettings.ImportAs goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives } + const megacheckName = "megacheck" + lcs := []*linter.Config{ linter.NewConfig(golinters.NewGovet(govetCfg)). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs, linter.PresetMetaLinter). WithAlternativeNames("vet", "vetshadow"). WithURL("https://golang.org/cmd/vet/"), linter.NewConfig(golinters.NewBodyclose()). + WithSince("v1.18.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance, linter.PresetBugs). WithURL("https://github.com/timakin/bodyclose"), linter.NewConfig(golinters.NewNoctx()). + WithSince("v1.28.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance, linter.PresetBugs). WithURL("https://github.com/sonatard/noctx"), linter.NewConfig(golinters.NewErrcheck()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs, linter.PresetError). WithURL("https://github.com/kisielk/errcheck"), linter.NewConfig(golinters.NewGolint()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithURL("https://github.com/golang/lint"), linter.NewConfig(golinters.NewRowsErrCheck()). + WithSince("v1.23.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs, linter.PresetSQL). WithURL("https://github.com/jingyugao/rowserrcheck"), linter.NewConfig(golinters.NewStaticcheck()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs, linter.PresetMetaLinter). WithAlternativeNames(megacheckName). WithURL("https://staticcheck.io/"), linter.NewConfig(golinters.NewUnused()). + WithSince("v1.20.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetUnused). WithAlternativeNames(megacheckName). @@ -167,255 +178,321 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithChangeTypes(). WithURL("https://github.com/dominikh/go-tools/tree/master/unused"), linter.NewConfig(golinters.NewGosimple()). + WithSince("v1.20.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithAlternativeNames(megacheckName). WithURL("https://github.com/dominikh/go-tools/tree/master/simple"), + linter.NewConfig(golinters.NewStylecheck()). + WithSince("v1.20.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithURL("https://github.com/dominikh/go-tools/tree/master/stylecheck"), - linter.NewConfig(golinters.NewGosec()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs). WithURL("https://github.com/securego/gosec"). WithAlternativeNames("gas"), linter.NewConfig(golinters.NewStructcheck()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetUnused). WithURL("https://github.com/opennota/check"), linter.NewConfig(golinters.NewVarcheck()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetUnused). WithURL("https://github.com/opennota/check"), linter.NewConfig(golinters.NewInterfacer()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithURL("https://github.com/mvdan/interfacer"). Deprecated("The repository of the linter has been archived by the owner."), linter.NewConfig(golinters.NewUnconvert()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithURL("https://github.com/mdempsky/unconvert"), linter.NewConfig(golinters.NewIneffassign()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetUnused). WithURL("https://github.com/gordonklaus/ineffassign"), linter.NewConfig(golinters.NewDupl()). + WithSince("v1.0.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/mibk/dupl"), linter.NewConfig(golinters.NewGoconst()). + WithSince(""). WithPresets(linter.PresetStyle). WithURL("https://github.com/jgautheron/goconst"), linter.NewConfig(golinters.NewDeadcode()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetUnused). WithURL("https://github.com/remyoudompheng/go-misc/tree/master/deadcode"), linter.NewConfig(golinters.NewGocyclo()). + WithSince("v1.0.0"). WithPresets(linter.PresetComplexity). WithURL("https://github.com/fzipp/gocyclo"), linter.NewConfig(golinters.NewCyclop(cyclopCfg)). + WithSince("v1.37.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetComplexity). WithURL("https://github.com/bkielbasa/cyclop"), linter.NewConfig(golinters.NewGocognit()). + WithSince("v1.20.0"). WithPresets(linter.PresetComplexity). WithURL("https://github.com/uudashr/gocognit"), linter.NewConfig(golinters.NewTypecheck()). + WithSince("v1.3.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs). WithURL(""), linter.NewConfig(golinters.NewAsciicheck()). + WithSince("v1.26.0"). WithPresets(linter.PresetBugs, linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/tdakkota/asciicheck"), linter.NewConfig(golinters.NewGofmt()). + WithSince("v1.0.0"). WithPresets(linter.PresetFormatting). WithAutoFix(). WithURL("https://golang.org/cmd/gofmt/"), linter.NewConfig(golinters.NewGofumpt()). + WithSince("v1.28.0"). WithPresets(linter.PresetFormatting). WithAutoFix(). WithURL("https://github.com/mvdan/gofumpt"), linter.NewConfig(golinters.NewGoimports()). + WithSince("v1.20.0"). WithPresets(linter.PresetFormatting, linter.PresetImport). WithAutoFix(). WithURL("https://godoc.org/golang.org/x/tools/cmd/goimports"), linter.NewConfig(golinters.NewGoHeader()). + WithSince("v1.28.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/denis-tingajkin/go-header"), linter.NewConfig(golinters.NewGci()). + WithSince("v1.30.0"). WithPresets(linter.PresetFormatting, linter.PresetImport). WithLoadForGoAnalysis(). WithAutoFix(). WithURL("https://github.com/daixiang0/gci"), linter.NewConfig(golinters.NewMaligned()). + WithSince("v1.0.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance). WithURL("https://github.com/mdempsky/maligned"). Deprecated("The repository of the linter has been archived by the owner. Use govet 'fieldalignment' instead."), linter.NewConfig(golinters.NewDepguard()). + WithSince("v1.4.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule). WithURL("https://github.com/OpenPeeDeeP/depguard"), linter.NewConfig(golinters.NewMisspell()). + WithSince("v1.8.0"). WithPresets(linter.PresetStyle, linter.PresetComment). WithAutoFix(). WithURL("https://github.com/client9/misspell"), linter.NewConfig(golinters.NewLLL()). + WithSince("v1.8.0"). WithPresets(linter.PresetStyle), linter.NewConfig(golinters.NewUnparam()). + WithSince("v1.9.0"). WithPresets(linter.PresetUnused). WithLoadForGoAnalysis(). WithURL("https://github.com/mvdan/unparam"), linter.NewConfig(golinters.NewDogsled()). + WithSince("v1.19.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/alexkohler/dogsled"), linter.NewConfig(golinters.NewNakedret()). + WithSince("v1.19.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/alexkohler/nakedret"), linter.NewConfig(golinters.NewPrealloc()). + WithSince("v1.19.0"). WithPresets(linter.PresetPerformance). WithURL("https://github.com/alexkohler/prealloc"), linter.NewConfig(golinters.NewScopelint()). + WithSince("v1.12.0"). WithPresets(linter.PresetBugs). WithURL("https://github.com/kyoh86/scopelint"). Deprecated("The repository of the linter has been deprecated by the owner. Use 'exportloopref' instead."), linter.NewConfig(golinters.NewGocritic()). + WithSince("v1.12.0"). WithPresets(linter.PresetStyle, linter.PresetMetaLinter). WithLoadForGoAnalysis(). WithURL("https://github.com/go-critic/go-critic"), linter.NewConfig(golinters.NewGochecknoinits()). + WithSince("v1.12.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/leighmcculloch/gochecknoinits"), linter.NewConfig(golinters.NewGochecknoglobals()). + WithSince("v1.12.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/leighmcculloch/gochecknoglobals"), linter.NewConfig(golinters.NewGodox()). + WithSince("v1.19.0"). WithPresets(linter.PresetStyle, linter.PresetComment). WithURL("https://github.com/matoous/godox"), linter.NewConfig(golinters.NewFunlen()). + WithSince("v1.18.0"). WithPresets(linter.PresetComplexity). WithURL("https://github.com/ultraware/funlen"), linter.NewConfig(golinters.NewWhitespace()). + WithSince("v1.19.0"). WithPresets(linter.PresetStyle). WithAutoFix(). WithURL("https://github.com/ultraware/whitespace"), linter.NewConfig(golinters.NewWSL()). + WithSince("v1.20.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/bombsimon/wsl"), linter.NewConfig(golinters.NewGoPrintfFuncName()). + WithSince("v1.23.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/jirfag/go-printf-func-name"), linter.NewConfig(golinters.NewGoMND(m.cfg)). + WithSince("v1.22.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/tommy-muehle/go-mnd"), linter.NewConfig(golinters.NewGoerr113()). + WithSince("v1.26.0"). WithPresets(linter.PresetStyle, linter.PresetError). WithLoadForGoAnalysis(). WithURL("https://github.com/Djarvur/go-err113"), linter.NewConfig(golinters.NewGomodguard()). + WithSince("v1.25.0"). WithPresets(linter.PresetStyle, linter.PresetImport, linter.PresetModule). WithLoadForGoAnalysis(). WithURL("https://github.com/ryancurrah/gomodguard"), linter.NewConfig(golinters.NewGodot()). + WithSince("v1.25.0"). WithPresets(linter.PresetStyle, linter.PresetComment). WithAutoFix(). WithURL("https://github.com/tetafro/godot"), linter.NewConfig(golinters.NewTestpackage(testpackageCfg)). + WithSince("v1.25.0"). WithPresets(linter.PresetStyle, linter.PresetTest). WithLoadForGoAnalysis(). WithURL("https://github.com/maratori/testpackage"), linter.NewConfig(golinters.NewNestif()). + WithSince("v1.25.0"). WithPresets(linter.PresetComplexity). WithURL("https://github.com/nakabonne/nestif"), linter.NewConfig(golinters.NewExportLoopRef()). + WithSince("v1.28.0"). WithPresets(linter.PresetBugs). WithLoadForGoAnalysis(). WithURL("https://github.com/kyoh86/exportloopref"), linter.NewConfig(golinters.NewExhaustive(exhaustiveCfg)). + WithSince(" v1.28.0"). WithPresets(linter.PresetBugs). WithLoadForGoAnalysis(). WithURL("https://github.com/nishanths/exhaustive"), linter.NewConfig(golinters.NewSQLCloseCheck()). + WithSince("v1.28.0"). WithPresets(linter.PresetBugs, linter.PresetSQL). WithLoadForGoAnalysis(). WithURL("https://github.com/ryanrolds/sqlclosecheck"), linter.NewConfig(golinters.NewNLReturn()). + WithSince("v1.30.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/ssgreg/nlreturn"), linter.NewConfig(golinters.NewWrapcheck()). + WithSince("v1.32.0"). WithPresets(linter.PresetStyle, linter.PresetError). WithLoadForGoAnalysis(). WithURL("https://github.com/tomarrell/wrapcheck"), linter.NewConfig(golinters.NewThelper(thelperCfg)). + WithSince("v1.34.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/kulti/thelper"), linter.NewConfig(golinters.NewTparallel()). + WithSince("v1.32.0"). WithPresets(linter.PresetStyle, linter.PresetTest). WithLoadForGoAnalysis(). WithURL("https://github.com/moricho/tparallel"), linter.NewConfig(golinters.NewExhaustiveStruct(exhaustiveStructCfg)). + WithSince("v1.32.0"). WithPresets(linter.PresetStyle, linter.PresetTest). WithLoadForGoAnalysis(). WithURL("https://github.com/mbilski/exhaustivestruct"), linter.NewConfig(golinters.NewErrorLint(errorlintCfg)). + WithSince("v1.32.0"). WithPresets(linter.PresetBugs, linter.PresetError). WithLoadForGoAnalysis(). WithURL("https://github.com/polyfloyd/go-errorlint"), linter.NewConfig(golinters.NewParallelTest()). + WithSince("v1.33.0"). WithPresets(linter.PresetStyle, linter.PresetTest). WithLoadForGoAnalysis(). WithURL("https://github.com/kunwardeep/paralleltest"), linter.NewConfig(golinters.NewMakezero()). + WithSince("v1.34.0"). WithPresets(linter.PresetStyle, linter.PresetBugs). WithLoadForGoAnalysis(). WithURL("https://github.com/ashanbrown/makezero"), linter.NewConfig(golinters.NewForbidigo()). + WithSince("v1.34.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/ashanbrown/forbidigo"), linter.NewConfig(golinters.NewIfshort(ifshortCfg)). + WithSince("v1.36.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/esimonov/ifshort"), linter.NewConfig(golinters.NewPredeclared(predeclaredCfg)). + WithSince("v1.35.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/nishanths/predeclared"), linter.NewConfig(golinters.NewRevive(reviveCfg)). + WithSince("v1.37.0"). WithPresets(linter.PresetStyle, linter.PresetMetaLinter). ConsiderSlow(). WithURL("https://github.com/mgechev/revive"), linter.NewConfig(golinters.NewDurationCheck()). + WithSince("v1.37.0"). WithPresets(linter.PresetBugs). WithLoadForGoAnalysis(). WithURL("https://github.com/charithe/durationcheck"), linter.NewConfig(golinters.NewWastedAssign()). + WithSince("v1.38.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/sanposhiho/wastedassign"), linter.NewConfig(golinters.NewImportAs(importAsCfg)). + WithSince("v1.38.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/julz/importas"), linter.NewConfig(golinters.NewNilErr()). + WithSince("v1.38.0"). WithLoadForGoAnalysis(). WithPresets(linter.PresetBugs). WithURL("https://github.com/gostaticanalysis/nilerr"), linter.NewConfig(golinters.NewForceTypeAssert()). + WithSince("v1.38.0"). WithPresets(linter.PresetStyle). WithLoadForGoAnalysis(). WithURL("https://github.com/gostaticanalysis/forcetypeassert"), linter.NewConfig(golinters.NewGoModDirectives(goModDirectivesCfg)). + WithSince("v1.39.0"). WithPresets(linter.PresetStyle, linter.PresetModule). WithLoadForGoAnalysis(). WithURL("https://github.com/ldez/gomoddirectives"), // nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives linter.NewConfig(golinters.NewNoLintLint()). + WithSince("v1.26.0"). WithPresets(linter.PresetStyle). WithURL("https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint/README.md"), } From 340d2a7a4949b61634d422118c4cbc7b57b47bbd Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Tue, 16 Mar 2021 01:54:13 +0100 Subject: [PATCH 2/4] feat: improve deprecation system. --- pkg/lint/linter/config.go | 28 ++++++++++++++++-------- pkg/lint/lintersdb/manager.go | 6 ++--- pkg/lint/runner.go | 11 ++++++++-- scripts/expand_website_templates/main.go | 9 ++++---- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/pkg/lint/linter/config.go b/pkg/lint/linter/config.go index 9f090a43ddd5..0bc664732c01 100644 --- a/pkg/lint/linter/config.go +++ b/pkg/lint/linter/config.go @@ -20,6 +20,12 @@ const ( PresetUnused = "unused" // Related to the detection of unused code. ) +type Deprecation struct { + Since string + Message string + Replacement string +} + type Config struct { Linter Linter EnabledByDefault bool @@ -29,13 +35,13 @@ type Config struct { InPresets []string AlternativeNames []string - OriginalURL string // URL of original (not forked) repo, needed for autogenerated README - CanAutoFix bool - IsSlow bool - DoesChangeTypes bool - DeprecatedMessage string + OriginalURL string // URL of original (not forked) repo, needed for autogenerated README + CanAutoFix bool + IsSlow bool + DoesChangeTypes bool - Since string + Since string + Deprecation *Deprecation } func (lc *Config) ConsiderSlow() *Config { @@ -89,13 +95,17 @@ func (lc *Config) WithSince(version string) *Config { return lc } -func (lc *Config) Deprecated(message string) *Config { - lc.DeprecatedMessage = message +func (lc *Config) Deprecated(message, version, replacement string) *Config { + lc.Deprecation = &Deprecation{ + Since: version, + Message: message, + Replacement: replacement, + } return lc } func (lc *Config) IsDeprecated() bool { - return lc.DeprecatedMessage != "" + return lc.Deprecation != nil } func (lc *Config) AllNames() []string { diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index c5437edfed90..9938ed4f889a 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -210,7 +210,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithLoadForGoAnalysis(). WithPresets(linter.PresetStyle). WithURL("https://github.com/mvdan/interfacer"). - Deprecated("The repository of the linter has been archived by the owner."), + Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", ""), linter.NewConfig(golinters.NewUnconvert()). WithSince("v1.0.0"). WithLoadForGoAnalysis(). @@ -289,7 +289,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithLoadForGoAnalysis(). WithPresets(linter.PresetPerformance). WithURL("https://github.com/mdempsky/maligned"). - Deprecated("The repository of the linter has been archived by the owner. Use govet 'fieldalignment' instead."), + Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", "govet 'fieldalignment'"), linter.NewConfig(golinters.NewDepguard()). WithSince("v1.4.0"). WithLoadForGoAnalysis(). @@ -324,7 +324,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithSince("v1.12.0"). WithPresets(linter.PresetBugs). WithURL("https://github.com/kyoh86/scopelint"). - Deprecated("The repository of the linter has been deprecated by the owner. Use 'exportloopref' instead."), + Deprecated("The repository of the linter has been deprecated by the owner.", "v1.39.0", "exportloopref"), linter.NewConfig(golinters.NewGocritic()). WithSince("v1.12.0"). WithPresets(linter.PresetStyle, linter.PresetMetaLinter). diff --git a/pkg/lint/runner.go b/pkg/lint/runner.go index 5788474705db..bf4382a7862c 100644 --- a/pkg/lint/runner.go +++ b/pkg/lint/runner.go @@ -52,9 +52,16 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, es *lint // print deprecated messages if !cfg.InternalCmdTest { for name, lc := range enabledLinters { - if lc.IsDeprecated() { - log.Warnf("The linter '%s' is deprecated due to: %s", name, lc.DeprecatedMessage) + if !lc.IsDeprecated() { + continue } + + var extra string + if lc.Deprecation.Replacement != "" { + extra = fmt.Sprintf(" Replaced by %s.", lc.Deprecation.Replacement) + } + + log.Warnf("The linter '%s' is deprecated (since %s) due to: %s %s", name, lc.Deprecation.Since, lc.Deprecation.Message, extra) } } diff --git a/scripts/expand_website_templates/main.go b/scripts/expand_website_templates/main.go index 8e6f379a2e13..df51cca40914 100644 --- a/scripts/expand_website_templates/main.go +++ b/scripts/expand_website_templates/main.go @@ -237,7 +237,7 @@ func getLintersListMarkdown(enabled bool) string { getDesc(lc), strings.Join(lc.InPresets, ", "), check(lc.CanAutoFix, "Auto fix supported"), - check(lc.DeprecatedMessage != "", "Deprecated"), + check(lc.IsDeprecated(), "Deprecated"), // FIXME improve message ) lines = append(lines, line) } @@ -252,7 +252,8 @@ func getName(lc *linter.Config) string { name = fmt.Sprintf("[%s](%s)", lc.Name(), lc.OriginalURL) } - if lc.DeprecatedMessage != "" { + if lc.IsDeprecated() { + // FIXME improve info name += ` ` } @@ -261,8 +262,8 @@ func getName(lc *linter.Config) string { func getDesc(lc *linter.Config) string { desc := lc.Linter.Desc() - if lc.DeprecatedMessage != "" { - desc = lc.DeprecatedMessage + if lc.IsDeprecated() { + desc = lc.Deprecation.Message // FIXME improve message } return strings.ReplaceAll(desc, "\n", "
") From 9dc7d4d16d0ae77a600765367b4448b976e59e25 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Tue, 16 Mar 2021 22:24:11 +0100 Subject: [PATCH 3/4] feat: improve linters page. --- scripts/expand_website_templates/main.go | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/scripts/expand_website_templates/main.go b/scripts/expand_website_templates/main.go index df51cca40914..e49fd6624ce5 100644 --- a/scripts/expand_website_templates/main.go +++ b/scripts/expand_website_templates/main.go @@ -227,8 +227,8 @@ func getLintersListMarkdown(enabled bool) string { }) lines := []string{ - "|Name|Description|Presets|AutoFix|Deprecated|", - "|---|---|---|---|---|", + "|Name|Description|Presets|AutoFix|Since|", + "|---|---|---|---|---|---|", } for _, lc := range neededLcs { @@ -237,7 +237,7 @@ func getLintersListMarkdown(enabled bool) string { getDesc(lc), strings.Join(lc.InPresets, ", "), check(lc.CanAutoFix, "Auto fix supported"), - check(lc.IsDeprecated(), "Deprecated"), // FIXME improve message + lc.Since, ) lines = append(lines, line) } @@ -252,18 +252,25 @@ func getName(lc *linter.Config) string { name = fmt.Sprintf("[%s](%s)", lc.Name(), lc.OriginalURL) } - if lc.IsDeprecated() { - // FIXME improve info - name += ` ` + if !lc.IsDeprecated() { + return name + } + + title := "deprecated" + if lc.Deprecation.Replacement != "" { + title += fmt.Sprintf(" since %s", lc.Deprecation.Since) } - return name + return name + " " + span(title, "⚠") } func getDesc(lc *linter.Config) string { desc := lc.Linter.Desc() if lc.IsDeprecated() { - desc = lc.Deprecation.Message // FIXME improve message + desc = lc.Deprecation.Message + if lc.Deprecation.Replacement != "" { + desc += fmt.Sprintf(" Replaced by %s.", lc.Deprecation.Replacement) + } } return strings.ReplaceAll(desc, "\n", "
") @@ -271,11 +278,15 @@ func getDesc(lc *linter.Config) string { func check(b bool, title string) string { if b { - return `` + return span(title, "✔") } return "" } +func span(title, icon string) string { + return fmt.Sprintf(`%s`, title, icon) +} + func getThanksList() string { var lines []string addedAuthors := map[string]bool{} From d689e6d6ea2aee422aa6f847a435bb4643393951 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 17 Mar 2021 15:03:28 +0100 Subject: [PATCH 4/4] improve contributing doc. --- docs/src/docs/contributing/new-linters.mdx | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/src/docs/contributing/new-linters.mdx b/docs/src/docs/contributing/new-linters.mdx index 61173e9bffd4..23494f2bb5da 100644 --- a/docs/src/docs/contributing/new-linters.mdx +++ b/docs/src/docs/contributing/new-linters.mdx @@ -9,31 +9,35 @@ from scratch and integrate it into `golangci-lint`. ## How to add a public linter to `golangci-lint` -You need to implement a new linter using `go/analysis` API. We don't accept not `go/analysis` linters. +You need to implement a new linter using `go/analysis` API. +We don't accept not `go/analysis` linters. After that: -1. Implement functional tests for the linter: add one file into directory [`test/testdata`](https://github.com/golangci/golangci-lint/tree/master/test/testdata). - Run `T=yourlintername.go make test_linters` to ensure that test fails. -2. Add a new file `pkg/golinters/{yourlintername}.go`. Look at other linters in this directory. Implement linter integration and check that test passes. +1. Implement functional tests for the linter: + - Add one file into directory [`test/testdata`](https://github.com/golangci/golangci-lint/tree/master/test/testdata). + - Run `T=yourlintername.go make test_linters` to ensure that test fails. + - Run `go run ./cmd/golangci-lint/ run --no-config --disable-all --enable=yourlintername ./test/testdata/yourlintername.go` +2. Add a new file `pkg/golinters/{yourlintername}.go`. + Look at other linters in this directory. + Implement linter integration and check that test passes. 3. Add the new struct for the linter (which you've implemented in `pkg/golinters/{yourlintername}.go`) to the list of all supported linters in [`pkg/lint/lintersdb/manager.go`](https://github.com/golangci/golangci-lint/blob/master/pkg/lint/lintersdb/manager.go) - to the function `GetAllSupportedLinterConfigs`. Enable it by default only if you are sure. -4. Find out what options do you need to configure for the linter. For example, `nakedret` has - only 1 option: [`max-func-lines`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml). + to the function `GetAllSupportedLinterConfigs`. + - Add `WithSince("next_version")`, where `next_version` must be replaced by the next minor version. (ex: v1.2.0 if the current version is v1.1.0) +4. Find out what options do you need to configure for the linter. + For example, `nakedret` has only 1 option: [`max-func-lines`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml). Choose default values to not being annoying for users of golangci-lint. Add configuration options to: - -- [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml) - the example of a configuration file. You can also add - them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) if you think - that this project needs not default values. -- [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go) - don't forget - about `mapstructure` tag for proper configuration files parsing by [pflag](https://github.com/spf13/pflag). - -5. Take a look at the example of [Pull Request with new linter support](https://github.com/golangci/golangci-lint/pull/850). + - [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml) - the example of a configuration file. + You can also add them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) + if you think that this project needs not default values. + - [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go) - + don't forget about `mapstructure` tag for proper configuration files parsing by [pflag](https://github.com/spf13/pflag). +5. Take a look at the example of [Pull Request with new linter support](https://github.com/golangci/golangci-lint/pulls?q=is%3Apr+is%3Amerged+label%3A%22linter%3A+new%22). ## How to add a private linter to `golangci-lint` -Some people and organizations may choose to have custom made linters run as a part of `golangci-lint`. +Some people and organizations may choose to have custom-made linters run as a part of `golangci-lint`. Typically, these linters can't be open-sourced or too specific. Such linters can be added through Go's plugin library.