Add versions, improve deprecation system, improve linters page (#1854)

This commit is contained in:
Ludovic Fernandez 2021-03-17 16:17:33 +01:00 committed by GitHub
parent b6a6faa982
commit 8db518cee0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 156 additions and 39 deletions

View File

@ -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.

View File

@ -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 {

View File

@ -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"),
}

View File

@ -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)
}
}

View File

@ -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 += ` <span title="deprecated">⚠</span>`
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", "<br/>")
@ -270,11 +278,15 @@ func getDesc(lc *linter.Config) string {
func check(b bool, title string) string {
if b {
return `<span title="` + title + `">✔</span>`
return span(title, "✔")
}
return ""
}
func span(title, icon string) string {
return fmt.Sprintf(`<span title="%s">%s</span>`, title, icon)
}
func getThanksList() string {
var lines []string
addedAuthors := map[string]bool{}