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.
diff --git a/pkg/lint/linter/config.go b/pkg/lint/linter/config.go
index 3d741803dc6a..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,11 +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
+ Deprecation *Deprecation
}
func (lc *Config) ConsiderSlow() *Config {
@@ -82,13 +90,22 @@ func (lc *Config) WithChangeTypes() *Config {
return lc
}
-func (lc *Config) Deprecated(message string) *Config {
- lc.DeprecatedMessage = message
+func (lc *Config) WithSince(version string) *Config {
+ lc.Since = version
+ return lc
+}
+
+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 55397eb59c87..9938ed4f889a 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."),
+ Deprecated("The repository of the linter has been archived by the owner.", "v1.38.0", ""),
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."),
+ 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().
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."),
+ 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).
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"),
}
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..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.DeprecatedMessage != "", "Deprecated"),
+ lc.Since,
)
lines = append(lines, line)
}
@@ -252,17 +252,25 @@ func getName(lc *linter.Config) string {
name = fmt.Sprintf("[%s](%s)", lc.Name(), lc.OriginalURL)
}
- if lc.DeprecatedMessage != "" {
- name += ` ⚠`
+ if !lc.IsDeprecated() {
+ return name
}
- return name
+ title := "deprecated"
+ if lc.Deprecation.Replacement != "" {
+ title += fmt.Sprintf(" since %s", lc.Deprecation.Since)
+ }
+
+ return name + " " + span(title, "⚠")
}
func getDesc(lc *linter.Config) string {
desc := lc.Linter.Desc()
- if lc.DeprecatedMessage != "" {
- desc = lc.DeprecatedMessage
+ if lc.IsDeprecated() {
+ desc = lc.Deprecation.Message
+ if lc.Deprecation.Replacement != "" {
+ desc += fmt.Sprintf(" Replaced by %s.", lc.Deprecation.Replacement)
+ }
}
return strings.ReplaceAll(desc, "\n", "
")
@@ -270,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{}