-
-
Save maratori/47a4d00457a92aa426dbd48a18776322 to your computer and use it in GitHub Desktop.
# This code is licensed under the terms of the MIT license https://opensource.org/license/mit | |
# Copyright (c) 2021 Marat Reymers | |
## Golden config for golangci-lint v1.62.0 | |
# | |
# This is the best config for golangci-lint based on my experience and opinion. | |
# It is very strict, but not extremely strict. | |
# Feel free to adapt and change it for your needs. | |
run: | |
# Timeout for analysis, e.g. 30s, 5m. | |
# Default: 1m | |
timeout: 3m | |
# This file contains only configs which differ from defaults. | |
# All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml | |
linters-settings: | |
cyclop: | |
# The maximal code complexity to report. | |
# Default: 10 | |
max-complexity: 30 | |
# The maximal average package complexity. | |
# If it's higher than 0.0 (float) the check is enabled | |
# Default: 0.0 | |
package-average: 10.0 | |
errcheck: | |
# Report about not checking of errors in type assertions: `a := b.(MyStruct)`. | |
# Such cases aren't reported by default. | |
# Default: false | |
check-type-assertions: true | |
exhaustive: | |
# Program elements to check for exhaustiveness. | |
# Default: [ switch ] | |
check: | |
- switch | |
- map | |
exhaustruct: | |
# List of regular expressions to exclude struct packages and their names from checks. | |
# Regular expressions must match complete canonical struct package/name/structname. | |
# Default: [] | |
exclude: | |
# std libs | |
- "^net/http.Client$" | |
- "^net/http.Cookie$" | |
- "^net/http.Request$" | |
- "^net/http.Response$" | |
- "^net/http.Server$" | |
- "^net/http.Transport$" | |
- "^net/url.URL$" | |
- "^os/exec.Cmd$" | |
- "^reflect.StructField$" | |
# public libs | |
- "^github.com/Shopify/sarama.Config$" | |
- "^github.com/Shopify/sarama.ProducerMessage$" | |
- "^github.com/mitchellh/mapstructure.DecoderConfig$" | |
- "^github.com/prometheus/client_golang/.+Opts$" | |
- "^github.com/spf13/cobra.Command$" | |
- "^github.com/spf13/cobra.CompletionOptions$" | |
- "^github.com/stretchr/testify/mock.Mock$" | |
- "^github.com/testcontainers/testcontainers-go.+Request$" | |
- "^github.com/testcontainers/testcontainers-go.FromDockerfile$" | |
- "^golang.org/x/tools/go/analysis.Analyzer$" | |
- "^google.golang.org/protobuf/.+Options$" | |
- "^gopkg.in/yaml.v3.Node$" | |
funlen: | |
# Checks the number of lines in a function. | |
# If lower than 0, disable the check. | |
# Default: 60 | |
lines: 100 | |
# Checks the number of statements in a function. | |
# If lower than 0, disable the check. | |
# Default: 40 | |
statements: 50 | |
# Ignore comments when counting lines. | |
# Default false | |
ignore-comments: true | |
gochecksumtype: | |
# Presence of `default` case in switch statements satisfies exhaustiveness, if all members are not listed. | |
# Default: true | |
default-signifies-exhaustive: false | |
gocognit: | |
# Minimal code complexity to report. | |
# Default: 30 (but we recommend 10-20) | |
min-complexity: 20 | |
gocritic: | |
# Settings passed to gocritic. | |
# The settings key is the name of a supported gocritic checker. | |
# The list of supported checkers can be find in https://go-critic.github.io/overview. | |
settings: | |
captLocal: | |
# Whether to restrict checker to params only. | |
# Default: true | |
paramsOnly: false | |
underef: | |
# Whether to skip (*x).method() calls where x is a pointer receiver. | |
# Default: true | |
skipRecvDeref: false | |
gomodguard: | |
blocked: | |
# List of blocked modules. | |
# Default: [] | |
modules: | |
- github.com/golang/protobuf: | |
recommendations: | |
- google.golang.org/protobuf | |
reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules" | |
- github.com/satori/go.uuid: | |
recommendations: | |
- github.com/google/uuid | |
reason: "satori's package is not maintained" | |
- github.com/gofrs/uuid: | |
recommendations: | |
- github.com/gofrs/uuid/v5 | |
reason: "gofrs' package was not go module before v5" | |
govet: | |
# Enable all analyzers. | |
# Default: false | |
enable-all: true | |
# Disable analyzers by name. | |
# Run `go tool vet help` to see all analyzers. | |
# Default: [] | |
disable: | |
- fieldalignment # too strict | |
# Settings per analyzer. | |
settings: | |
shadow: | |
# Whether to be strict about shadowing; can be noisy. | |
# Default: false | |
strict: true | |
inamedparam: | |
# Skips check for interface methods with only a single parameter. | |
# Default: false | |
skip-single-param: true | |
mnd: | |
# List of function patterns to exclude from analysis. | |
# Values always ignored: `time.Date`, | |
# `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`, | |
# `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`. | |
# Default: [] | |
ignored-functions: | |
- args.Error | |
- flag.Arg | |
- flag.Duration.* | |
- flag.Float.* | |
- flag.Int.* | |
- flag.Uint.* | |
- os.Chmod | |
- os.Mkdir.* | |
- os.OpenFile | |
- os.WriteFile | |
- prometheus.ExponentialBuckets.* | |
- prometheus.LinearBuckets | |
nakedret: | |
# Make an issue if func has more lines of code than this setting, and it has naked returns. | |
# Default: 30 | |
max-func-lines: 0 | |
nolintlint: | |
# Exclude following linters from requiring an explanation. | |
# Default: [] | |
allow-no-explanation: [ funlen, gocognit, lll ] | |
# Enable to require an explanation of nonzero length after each nolint directive. | |
# Default: false | |
require-explanation: true | |
# Enable to require nolint directives to mention the specific linter being suppressed. | |
# Default: false | |
require-specific: true | |
perfsprint: | |
# Optimizes into strings concatenation. | |
# Default: true | |
strconcat: false | |
rowserrcheck: | |
# database/sql is always checked | |
# Default: [] | |
packages: | |
- github.com/jmoiron/sqlx | |
sloglint: | |
# Enforce not using global loggers. | |
# Values: | |
# - "": disabled | |
# - "all": report all global loggers | |
# - "default": report only the default slog logger | |
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global | |
# Default: "" | |
no-global: "all" | |
# Enforce using methods that accept a context. | |
# Values: | |
# - "": disabled | |
# - "all": report all contextless calls | |
# - "scope": report only if a context exists in the scope of the outermost function | |
# https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only | |
# Default: "" | |
context: "scope" | |
tenv: | |
# The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures. | |
# Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked. | |
# Default: false | |
all: true | |
linters: | |
disable-all: true | |
enable: | |
## enabled by default | |
- errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases | |
- gosimple # specializes in simplifying a code | |
- govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string | |
- ineffassign # detects when assignments to existing variables are not used | |
- staticcheck # is a go vet on steroids, applying a ton of static analysis checks | |
- typecheck # like the front-end of a Go compiler, parses and type-checks Go code | |
- unused # checks for unused constants, variables, functions and types | |
## disabled by default | |
- asasalint # checks for pass []any as any in variadic func(...any) | |
- asciicheck # checks that your code does not contain non-ASCII identifiers | |
- bidichk # checks for dangerous unicode character sequences | |
- bodyclose # checks whether HTTP response body is closed successfully | |
- canonicalheader # checks whether net/http.Header uses canonical header | |
- copyloopvar # detects places where loop variables are copied (Go 1.22+) | |
- cyclop # checks function and package cyclomatic complexity | |
- dupl # tool for code clone detection | |
- durationcheck # checks for two durations multiplied together | |
- errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error | |
- errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 | |
- exhaustive # checks exhaustiveness of enum switch statements | |
- fatcontext # detects nested contexts in loops | |
- forbidigo # forbids identifiers | |
- funlen # tool for detection of long functions | |
- gocheckcompilerdirectives # validates go compiler directive comments (//go:) | |
- gochecknoglobals # checks that no global variables exist | |
- gochecknoinits # checks that no init functions are present in Go code | |
- gochecksumtype # checks exhaustiveness on Go "sum types" | |
- gocognit # computes and checks the cognitive complexity of functions | |
- goconst # finds repeated strings that could be replaced by a constant | |
- gocritic # provides diagnostics that check for bugs, performance and style issues | |
- gocyclo # computes and checks the cyclomatic complexity of functions | |
- godot # checks if comments end in a period | |
- goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt | |
- gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod | |
- gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations | |
- goprintffuncname # checks that printf-like functions are named with f at the end | |
- gosec # inspects source code for security problems | |
- iface # checks the incorrect use of interfaces, helping developers avoid interface pollution | |
- intrange # finds places where for loops could make use of an integer range | |
- lll # reports long lines | |
- loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap) | |
- makezero # finds slice declarations with non-zero initial length | |
- mirror # reports wrong mirror patterns of bytes/strings usage | |
- mnd # detects magic numbers | |
- musttag # enforces field tags in (un)marshaled structs | |
- nakedret # finds naked returns in functions greater than a specified function length | |
- nestif # reports deeply nested if statements | |
- nilerr # finds the code that returns nil even if it checks that the error is not nil | |
- nilnil # checks that there is no simultaneous return of nil error and an invalid value | |
- noctx # finds sending http request without context.Context | |
- nolintlint # reports ill-formed or insufficient nolint directives | |
- nonamedreturns # reports all named returns | |
- nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL | |
- perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative | |
- predeclared # finds code that shadows one of Go's predeclared identifiers | |
- promlinter # checks Prometheus metrics naming via promlint | |
- protogetter # reports direct reads from proto message fields when getters should be used | |
- reassign # checks that package variables are not reassigned | |
- recvcheck # checks for receiver type consistency | |
- revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint | |
- rowserrcheck # checks whether Err of rows is checked successfully | |
- sloglint # ensure consistent code style when using log/slog | |
- spancheck # checks for mistakes with OpenTelemetry/Census spans | |
- sqlclosecheck # checks that sql.Rows and sql.Stmt are closed | |
- stylecheck # is a replacement for golint | |
- tenv # detects using os.Setenv instead of t.Setenv since Go1.17 | |
- testableexamples # checks if examples are testable (have an expected output) | |
- testifylint # checks usage of github.com/stretchr/testify | |
- testpackage # makes you use a separate _test package | |
- tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes | |
- unconvert # removes unnecessary type conversions | |
- unparam # reports unused function parameters | |
- usestdlibvars # detects the possibility to use variables/constants from the Go standard library | |
- wastedassign # finds wasted assignment statements | |
- whitespace # detects leading and trailing whitespace | |
## you may want to enable | |
#- decorder # checks declaration order and count of types, constants, variables and functions | |
#- exhaustruct # [highly recommend to enable] checks if all structure fields are initialized | |
#- gci # controls golang package import order and makes it always deterministic | |
#- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega | |
#- godox # detects FIXME, TODO and other comment keywords | |
#- goheader # checks is file header matches to pattern | |
#- inamedparam # [great idea, but too strict, need to ignore a lot of cases by default] reports interfaces with unnamed method parameters | |
#- interfacebloat # checks the number of methods inside an interface | |
#- ireturn # accept interfaces, return concrete types | |
#- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated | |
#- tagalign # checks that struct tags are well aligned | |
#- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope | |
#- wrapcheck # checks that errors returned from external packages are wrapped | |
#- zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event | |
## disabled | |
#- containedctx # detects struct contained context.Context field | |
#- contextcheck # [too many false positives] checks the function whether use a non-inherited context | |
#- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages | |
#- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) | |
#- dupword # [useless without config] checks for duplicate words in the source code | |
#- err113 # [too strict] checks the errors handling expressions | |
#- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted | |
#- exportloopref # [not necessary from Go 1.22] checks for pointers to enclosing loop variables | |
#- forcetypeassert # [replaced by errcheck] finds forced type assertions | |
#- gofmt # [replaced by goimports] checks whether code was gofmt-ed | |
#- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed | |
#- gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase | |
#- grouper # analyzes expression groups | |
#- importas # enforces consistent import aliases | |
#- maintidx # measures the maintainability index of each function | |
#- misspell # [useless] finds commonly misspelled English words in comments | |
#- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity | |
#- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test | |
#- tagliatelle # checks the struct tags | |
#- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers | |
#- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines | |
issues: | |
# Maximum count of issues with the same text. | |
# Set to 0 to disable. | |
# Default: 3 | |
max-same-issues: 50 | |
exclude-rules: | |
- source: "(noinspection|TODO)" | |
linters: [ godot ] | |
- source: "//noinspection" | |
linters: [ gocritic ] | |
- path: "_test\\.go" | |
linters: | |
- bodyclose | |
- dupl | |
- errcheck | |
- funlen | |
- goconst | |
- gosec | |
- noctx | |
- wrapcheck |
@Broderick-Westrope, thanks for your contribution. I'd appreciate it if you had more ideas on how to improve the config.
I've added functions from the flag
package to the ignored-functions
list. As this is a regexp, it will work for github.com/spf13/pflag
as well.
Note:
Unfortunately, gomnd
uses spelling from the code to match ignored-functions
(see gomd) instead of fully specified names. So the config will not work if you use dot import or import alias. Also, it doesn't work for methods of flag.FlagSet
.
@maratori that's awesome, thankyou.
@maratori possibly another for gomnd
ignored-functions
. I was using the NewWriter
function (Init
also has a similar signature and more documentation) from text/tabwriter
today and I haven't added it to my config yet but I think I will. I'm interested to hear your thoughts (and others) on whether things like formatting tab widths should be stored as a variable or if they are okay to hard code. The suggested changes are below. Thanks.
gomnd:
...
ignored-functions:
...
- tabwriter.NewWriter
- tabwriter.Init
@Broderick-Westrope, I think tabwriter
isn't used frequently. I'd prefer not to add it to the config.
No worries :)
https://github.com/ultraware/funlen
funlen
does not seem to have the option ignore-comments
to ignore counting of lines
Thank you very much for this @maratori ! That's the perfect config for me 👍
gomodguard:
blocked:
modules:
- github.com/gofrs/uuid:
recommendations:
- github.com/google/uuid
reason: "gofrs' package is not go module"
Looks like it is a go module already https://github.com/gofrs/uuid/releases/tag/v5.0.0
@shashkin thanks, removed from the config
@maratori The module is actually referenced as github.com/gofrs/uuid/v5
so I think it would be better to keep it in config but change the recommendation like this
gomodguard:
blocked:
modules:
- github.com/gofrs/uuid:
recommendations:
- github.com/gofrs/uuid/v5
reason: "gofrs' package was not go module before v5"
@shashkin good catch, updated
Hi, first of all thanks for the great work. It looks like https://golangci-lint.run/usage/linters/#perfsprint doesn't accept the strconcat
argument any longer.
gomodguard dont't work with standard library.
depguard work with standard library, for example
deny:
- pkg: $log
desc: "use slog or internal"
@skosovsky do you want me to enable depguard
instead of gomodguard
in this config?
@skosovsky do you want me to enable
depguard
instead ofgomodguard
in this config?
yes, depguard
also has versioning support for external packages, from docs:
A Prefix List just means that a package will match a value, if the value is a prefix of the package. Example github.com/OpenPeeDeeP/depguard package will match a value of github.com/OpenPeeDeeP but won't match github.com/OpenPeeDeeP/depguard/v2.
exportloopref
should disable since Go 1.22 because this problem no longer occurs and fixed by Go team
@chenyanchen thanks, disabled exportloopref
and copyloopvar
@maratori do you think copyloopvar
should be enabled by default? it allows us to clean the codebase where we copy the loop variables like n := n
pre-1.22
@brlala you are right. It was a mistake to disable it. Now, it's enabled.
@maratori long time to see!
Do you think it's finally time to update year in Copyright Notice? :D https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322#file-golangci-yml-L2
Jokes aside, what do you think about providing default, maybe commented out, config for tagliatelle
? It's pretty nice linter (unless you need to make something compatible with some weird existing naming schemes). But its default parameters are not so clear to comprehend — I need to remember to change json: "snake"
every damn time. Is my chose optioned? Yes. But let's make it clear on how it can be changed.
WDYT?
Thanks a lot
Very grateful!
Thanks a lot!
Hi @maratori, love this config. Just wondering your thoughts on adding
flag.Int
to theignored-functions
forgomnd
? I often find myself adding this in for each project, but I'm unsure if I should be doing this a better way? Thanks