Skip to content

🌟 Let's talk about linters section of the configuration #5299

Closed
@ldez

Description

@ldez

Important

This is a proposal: I don't know if it is possible and what the impact could be inside the code.
The proposal may evolve.


This is an attempt to summarize and provide a solution for the management of the linters inside the configuration.

The current configuration looks like this:

linters:
  disable-all: true
  enable:
    - lintera
    - linterb
    - ...
  enable-all: true
  disable:
    - linterc
    - linterd
    - ...
  presets:
    - bugs
    - comment
    - complexity
    - ...
  fast: true

linters-settings:
  lintera:
    opt1: foo
  # ...

⛑️ The Problems

Presets

Existing presets
  • 🐛: bugs
  • 💬: comment
  • 🧮: complexity
  • 💢: error
  • 💾: format
  • 🔝: import
  • 🎛️: metalinter
  • 📦: module
  • 📊: performance
  • 🗂️: sql
  • 🎩: style
  • 🚦: test
  • 🧹: unused
🐛 💬 🧮 💢 💾 🔝 🎛️️ 📦 📊 🗂️️ 🎩 🚦 🧹
asasalint 🐛
asciicheck 🐛 🎩
bidichk 🐛
bodyclose 🐛 📊
canonicalheader 🎩
containedctx 🎩
contextcheck 🐛
copyloopvar 🎩
cyclop 🧮
decorder 🎩
depguard 🔝 📦 🎩
dogsled 🎩
dupl 🎩
dupword 💬
durationcheck 🐛
err113 💢 🎩
errcheck 🐛 💢
errchkjson 🐛
errname 🎩
errorlint 🐛 💢
exhaustive 🐛
exhaustruct 🎩 🚦
exptostd 🎩
fatcontext 📊
forbidigo 🎩
forcetypeassert 🎩
funlen 🧮
gci 💾 🔝
ginkgolinter 🎩
gocheckcompilerdirectives 🐛
gochecknoglobals 🎩
gochecknoinits 🎩
gochecksumtype 🐛
gocognit 🧮
goconst 🎩
gocritic 🎛️ 🎩
gocyclo 🧮
godot 💬 🎩
godox 💬 🎩
gofmt 💾
gofumpt 💾
goheader 🎩
goimports 💾 🔝
gomoddirectives 📦 🎩
gomodguard 🔝 📦 🎩
goprintffuncname 🎩
gosec 🐛
gosimple 🎩
gosmopolitan 🐛
govet 🐛 🎛️
grouper 🎩
iface 🎩
importas 🎩
inamedparam 🎩
ineffassign 🧹
interfacebloat 🎩
intrange 🎩
ireturn 🎩
lll 🎩
loggercheck 🐛 🎩
maintidx 🧮
makezero 🐛 🎩
mirror 🎩
misspell 💬 🎩
mnd 🎩
musttag 🐛 🎩
nakedret 🎩
nestif 🧮
nilerr 🐛
nilnesserr 🐛
nilnil 🎩
nlreturn 🎩
noctx 🐛 📊
nolintlint 🎩
nonamedreturns 🎩
nosprintfhostport 🎩
paralleltest 🎩 🚦
perfsprint 📊
prealloc 📊
predeclared 🎩
promlinter 🎩
protogetter 🐛
reassign 🐛
recvcheck 🐛
revive 🎛️ 🎩
rowserrcheck 🐛 🗂️
sloglint 🎩
spancheck 🐛
sqlclosecheck 🐛 🗂️
staticcheck 🐛 🎛️
stylecheck 🎩
tagalign 🎩
tagliatelle 🎩
tenv 🚦
testableexamples 🚦
testifylint 🐛 🚦
testpackage 🎩 🚦
thelper 🚦
tparallel 🎩 🚦
unconvert 🎩
unparam 🧹
unused 🧹
usestdlibvars 🎩
usetesting 🚦
varnamelen 🎩
wastedassign 🎩
whitespace 🎩
wrapcheck 💢 🎩
wsl 🎩
zerologlint 🐛

The current presets option is not related to "presets" but to "categories"/topics.
The scope of a preset is too large because they are "categories"/topics and not a consistent or recommended subset of linters as expected by the name "presets".

I think this is difficult to use because there are a lot of linters, linters are in several "presets", and a "preset" can contain potential "incompatible" linters.

ex:

  • preset complexity: cyclop and gocyclo are redundant
  • preset format: gci, gofmt, gofumpt, goimports are mainly redudant (cf proposal about formatters) and "incompatible".
  • preset bugs: exhaustive, gochecksumtype can be related to bugs but they are very specific.
  • rowserrcheck is inside sql and bugs
  • etc.

Note: I use quotes around the word "categories" because it can be ambiguous due to the field Category inside the analysis.Diagnostic structure.

Default Linters

The current default set of linters is small and contains only "slow linters" and cannot be changed without a breaking change.

enable-all and disable-all

The options enable-all and disable-all are extremely useful.

But they have some "unexpected" behaviors:

  • disable cannot be used with disable-all
  • enable cannot be used with enable-all

In some way, these options are fighting against the default set of linters.

Fast

The fast option has an unexpected behavior: this is not a real filter.

  • disable-all: true:
    • presets -> fast -> enable -> disable: filter only linters from presets, linters defined inside enable are not filtered
  • enable-all: true
    • "all" -> presets -> fast -> enable -> disable: filter only "all" (+ presets but presets are useless because "all"), linters defined inside enable are not filtered.
  • default
    • presets -> fast -> enable -> disable: filter only default + presets, linters defined inside enable are not filtered

#1909 (comment)

Misc.

Also linters-settings option name contains a grammatical error: it should be linter-settings (note the s at the end of the word linter).

💭 The Proposal

  • Removes (deprecates) the presets option. For now, I don't know if it is useful to provide a replacement due to the nature of this option but maybe topics.
  • Removes (deprecates) enable-all and disable-all options.
  • Removes (deprecates) the fast option.
  • Adds a new option default:
    • This option will be a string (not a slice).
    • It will define the default set of linters
      • standard (or default-v1, or legacy): It enables the current default set of linters. This value will be the default.
        • if we use default-v1, or legacy, we can create a new set of "default" linters called standard or default-v2.
      • all: this is the equivalent of enable-all. It enables all linters.
      • none: this is the equivalent of disable-all. It disables all linters.
      • fast: Similar to the current fast. It enables all "fast" linters but this is not a filter on other enabled linters.
      • recommended: an "evolving" list of linters that we recommend for all projects. (This one can be ambiguous, so we can ignore it for now)
  • Adds a flag-only option --fast-only: a filter on the enabled linters. (similar to --enable-only)
  • Removes (deprecates) the section linters-settings and replace it with a subsection settings inside linters
linters:
  default: standard # standard/all/none/fast
  enable:
    - lintera
    - linterb
    - ...
  disable:
    - linterc
    - linterd
    - ...
  settings:
    lintera:
      opt1: foo
    # ...

Caution

Shareable configuration is another topic, and will not be handled in v2, so everything related to that is off-topic for now.
But be sure that the topic will be handled in the future.

Metadata

Metadata

Assignees

Labels

area: configRelated to .golangci.yml and/or cli optionsproposal

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions