Skip to content

Instantly share code, notes, and snippets.

@kulti
Last active June 25, 2024 23:44
Show Gist options
  • Save kulti/25f9243939e699428f7e14c5a3c8c32c to your computer and use it in GitHub Desktop.
Save kulti/25f9243939e699428f7e14c5a3c8c32c to your computer and use it in GitHub Desktop.
golangci-lint config workflow
# Comments started with [!] are explanations of my workflow with golangci-lint.
# Another comments are real comments in my config.
# [!] Examine the https://golangci-lint.run/usage/configuration/ to know all possibilities.
run:
timeout: 5m
modules-download-mode: vendor # [!] if you are using vendoring
build-tags:
- integration # [!] If you disable code for integration tests to run all unit tests, enable it to lint all the same.
# [!] Linters are enabled manually. Disabled linters are commented and have comment about reason of disabling.
# [!] Linters disabled inside source code by //nolint should be specific and comments like this
# [!] //nolint:gocyclo // This legacy function is complex but the team too busy to simplify it.
# [!] (see also nolintlint settings).
#
# [!] During update version of golangci-lint do the following:
# [!] - add new linters to enable-list
# [!] - enable previously disabled linters if needed
# [!] - configure (see below) or disable new linters to be appropriate for your project
linters:
disable-all: true
enable:
- asciicheck
- bidichk
- bodyclose
- contextcheck
# - cyclop
# Measuring code complexity is hard. Cyclomatic complexity is doubtfully
# a reliable metric for this purpose. Some problems are complex by nature
# and therefore more cyclomatically complex code might actually be
# simpler.
- deadcode
- depguard
- dogsled
- dupl
- durationcheck
- errname
- errcheck
- errorlint
- exhaustive
# - exhaustivestruct
# We frequently make use of zero-values and partial initialization.
- exportloopref
- forbidigo
- forcetypeassert
- funlen
- gci
- gochecknoglobals
- gochecknoinits
- gocognit
- goconst
- gocritic
- gocyclo
- godot
# - godox
# TODOs and FIXMEs function as a big warning sign: "Beware! This code has
# bugs and other problems. Be careful not to make things worse when
# editing. Or better fix the issues before implementing a new feature on
# top.". The idea of [`godox` comment
# extractor](https://github.com/766b/godox) seems to be different from
# the idea of [`godox` linter](https://github.com/matoous/godox). The
# first one lets you quickly browse through the code problems, while the
# second one asks you to remove that big warning sign in favor of tasks.
# Though tasks are great, they will not help you while editing.
- goerr113
- gofmt
- gofumpt
- goheader
- goimports
# - golint # Replaced by `revive`.
- gomnd
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- govet
- ifshort
- importas
# - ireturn # See: https://github.com/go-proverbs/go-proverbs.github.io/issues/37.
- ineffassign
# - interfacer # Is prone to bad suggestions (officialy deprecated).
- lll
# - maligned # Replaced by `govet`'s `fieldalignment`
- makezero
- misspell
- nakedret
- nestif
- nilnil # Zero-value of maps, slices and channels is `nil` but useful.
- nilerr
# - nlreturn # Too subjective.
- noctx
- nolintlint
- paralleltest
- prealloc
- predeclared
- promlinter
- revive
- rowserrcheck
# - scopelint # Replaced by `exportloopref`.
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- tagliatelle
- tenv
- testpackage
- thelper
- tparallel
- typecheck
- unconvert
- unparam
# - varnamelen
# Though the idea is idiomatic, the length is not the only thing that
# determines whether a variable is "easy to use".
- unused
- varcheck
- wastedassign
- whitespace
# - wrapcheck # Is prone to bad suggestions (especially see issue #1).
# - wsl # Too aggressive. Might be useful if it could do auto fix.
# [!] Linters has a lot of settings and can be flexible configured.
linters-settings:
lll:
line-length: 110
gci:
local-prefixes: <your go module>
forbidigo: # [!] Useful to check some code writing rules. E.g. this config contains example of using own logger instead of gloabl zap.
forbid:
- zap # we use our own logger that wraps zap.
- os.Exit # it's not safe to exit in random places, because defer will not work.
- log.Fatal.* # it calls os.Exit (see above)
# - c.viper # forbid it after full migrate to new declarative configs (see PLFM-616).
nilnil:
checked-types: # [!] choose only types relative to your code base or disable this linter.
- ptr
- func
- iface
nolintlint:
require-explanation: true # [!] it forces you to write explantion of //nolint comments.
require-specific: true
tagliatelle: # [!] configure it accordingly to your project rules.
case:
use-field-name: false
rules:
json: snake
yaml: snake
# [!] Extremly useful section to disable some linters.
issues:
exclude-rules:
- path: (_test\.go|apitest)
linters:
- forcetypeassert # it's ok to have some type risks in tests
- gosec # security is not make sense in tests
- noctx # it's ok to do simple http request without context in tests
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# They are using same environment
- path: tests/integration
linters:
- paralleltest
# Init and New functions is a glue for service. They can be long, but simple.
- linters:
- funlen
path: service\.go
source: "Init|New"
# We allow to use zap only in log package.
- path: internal/log
linters:
- forbidigo
text: "use of .* forbidden by pattern `zap`"
# We allow to log.Fatal in main, tests, scripts and generators.
- path: main.go|main_test.go|tests|scripts|internal/blueprint/generator/generator.go|build/dockergen.go
linters:
- forbidigo
text: "forbidden by pattern `log.Fatal.*`"
# We allow to os.Exit in main, tests, scripts and generators.
- path: main.go|main_test.go|tests|scripts|internal/blueprint/generator/generator.go|build/dockergen.go
linters:
- forbidigo
text: "forbidden by pattern `os.Exit`"
# We have a lot of nil-tolerant types here.
- path: <package with a lot of nil-tolerant types>
linters:
- nilnil
# Should be fixed after full migration to generated config PLFM-616.
- path: config.go
linters:
- unparam
text: "newConfig - result 1 \\(error\\) is always nil"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment