# Kudos to Oleg Kovalov https://olegk.dev/go-linters-configuration-the-right-version run: # Depends on your hardware concurrency: 1 timeout: 30m # Fail if the error was met. issues-exit-code: 1 # Check for bugs in tests. tests: false skip-dirs: - (^|/)vendor($|/) - (^|/)test($|/) skip-files: - .*_test.go # When enabled linter will skip directories: vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ skip-dirs-use-default: false # With the read-only mode linter will fail if the go.mod file is outdated. modules-download-mode: readonly # Never ran 2 golangci-lint at once. allow-parallel-runners: false # Keep this empty to use the Go version from the go.mod file. go: "" linters: # Set to true runs only fast linters. # Good option for 'lint on save', pre-commit hook or CI. fast: false enable: # Check for pass []any as any in variadic func(...any). # Rare case but saved me from debugging a few times. - asasalint # I prefer plane ASCII identifiers. # Symbol `∆` instead of `delta` looks cool but no, thanks. - asciicheck # Checks for dangerous unicode character sequences. # Super rare but why not to be a bit paranoid? - bidichk # Checks whether HTTP response body is closed successfully. - bodyclose # Check whether the function uses a non-inherited context. - contextcheck # Check for two durations multiplied together. - durationcheck # Forces to not skip error check. - errcheck # Checks `Err-` prefix for var and `-Error` suffix for error type. - errname # Suggests to use `%w` for error-wrapping. - errorlint # Checks for pointers to enclosing loop variables. - exportloopref # Finds forced type assertions. - forcetypeassert # Imports order. - gci # Almost 100 diagnostics that check for bugs, performance and style issues # Highly extensible Go source code linter providing checks currently missing from other linters. - gocritic # Forces to put `.` at the end of the comment. - godot # Might not be that important, but I prefer to keep all of them. # `gofumpt` is amazing, kudos to Daniel Marti https://github.com/mvdan/gofumpt - gofmt - gofumpt - goimports # Reports magic consts. Might be noisy but still good. - gomnd # Allow or ban replace directives in go.mod # or force explanation for retract directives. - gomoddirectives # Allowed/blocked packages to import. - gomodguard # Powerful security-oriented linter. But requires some time to # configure it properly, see https://github.com/securego/gosec#available-rules - gosec # Linter that specializes in simplifying code. - gosimple # Official Go tool. Must have. - govet # Groupt declarations. - grouper # Detects when assignments to existing variables are not used. - ineffassign # Even with deprecation notice I find it useful. # There are situations when instead of io.ReaderCloser # I can use io.Reader. A small but good improvement. - interfacer # Some log checkers, might be useful. - loggercheck # Fix all the misspellings, amazing thing. - misspell # Finds naked/bare returns and requires change them. - nakedret # Both require a bit more explicit returns. - nilerr - nilnil # Forces newlines in some places. - nlreturn # Finds sending HTTP request without context.Context. - noctx # Forces comment why another check is disabled. # Better not to have //nolint: at all ;) - nolintlint # Finds slices that could potentially be pre-allocated. # Small performance win + cleaner code. - prealloc # Finds shadowing of Go's predeclared identifiers. - predeclared # Lint your Prometheus metrics name. - promlinter # Checks that package variables are not reassigned. # Super rare case but can catch bad things (like `io.EOF = nil`) - reassign # Drop-in replacement of `golint`. - revive # Somewhat similar to `bodyclose` but for `database/sql` package. - rowserrcheck - sqlclosecheck # I have found that it's not the same as staticcheck binary :\ - staticcheck # Is a replacement for `golint`, similar to `revive`. - stylecheck # Check struct tags. - tagliatelle # Test-related checks. All of them are good. - tenv - testableexamples - thelper - tparallel # Remove unnecessary type conversions, make code cleaner - unconvert # Might be noisy but better to know what is unused - unparam # Must have. Finds unused declarations. - unused # Detect the possibility to use variables/constants from stdlib. - usestdlibvars # Finds wasted assignment statements. - wastedassign disable: # Detects struct contained context.Context field. Not a problem. - containedctx # Checks function and package cyclomatic complexity. # I can have a long but trivial switch-case. # # Cyclomatic complexity is a measurement, not a goal. # (c) Bryan C. Mills / https://github.com/bcmills - cyclop # Deprecated, replaced by `unused`. - deadcode # Check declaration order of types, consts, vars and funcs. - decorder # Checks if package imports are in a list of acceptable packages. - depguard # Checks assignments with too many blank identifiers. Very rare. - dogsled # Tool for code clone detection. - dupl # Find duplicate words, rare. - dupword # I'm fine to check the error from json.Marshal - errchkjson # All SQL queries MUST BE covered with tests. - execinquery # Forces to handle more cases. Cool but noisy. - exhaustive - exhaustivestruct # Deprecated, replaced by check below. - exhaustruct # Forbids some identifiers. I don't have a case for it. - forbidigo # I might have long but a simple function. - funlen # Globals and init() are ok. - gochecknoglobals - gochecknoinits # Same as `cyclop` linter (see above) - gocognit - goconst - gocyclo # TODO and friends are ok. - godox # Check the error handling expressions. Too noisy. - goerr113 # I don't use file headers. - goheader # 1st Go linter, deprecated :( use `revive`. - golint # Printf-like functions must have -f. - goprintffuncname # Deprecated - ifshort # Checks imports aliases, rare. - importas # Forces tiny interfaces, very subjective. - interfacebloat # Accept interfaces, return types. Not always. - ireturn # I don't set line length. - lll # Maintainability index of each function, subjective. - maintidx # Slice declarations with non-zero initial length. - makezero # Deprecated. Use govet `fieldalignment`. - maligned # Deeply nested if statements, subjective. - nestif # Reports all named returns, not that bad. - nonamedreturns # Deprecated. Replaced by `revive`. - nosnakecase # Finds misuse of Sprintf with host:port in a URL. Cool but rare. - nosprintfhostport # I don't use t.Parallel() that much. - paralleltest # Deprecated - scopelint # Deprecated - structcheck # Often non-`_test` package is ok. - testpackage # Compiler can do it too :) - typecheck # Deprecated - varcheck # I'm fine with long variable names with a small scope. - varnamelen # gofmt,gofumpt covers that (from what I know). - whitespace # Don't find it useful to wrap all errors from external packages. - wrapcheck # Forces you to use empty lines. Great if configured correctly. # I mean there is an agreement in a team. - wsl linters-settings: # I'm biased, and I'm enabling more than 100 checks # Might be too much for you. See https://go-critic.com/overview.html gocritic: enabled-tags: - diagnostic - experimental - opinionated - performance - style disabled-checks: # These 3 will detect many cases, but they do sense # if it's performance oriented code - hugeParam - rangeExprCopy - rangeValCopy errcheck: # Report `a := b.(MyStruct)` when `a, ok := ...` should be. check-type-assertions: true # Default: false # Report skipped checks:`num, _ := strconv.Atoi(numStr)`. check-blank: true # Default: false # Function to skip. exclude-functions: - io/ioutil.ReadFile - io.Copy(*bytes.Buffer) - io.Copy(os.Stdout) govet: disable: - fieldalignment # I'm ok to waste some bytes nakedret: # No naked returns, ever. max-func-lines: 1 # Default: 30 tagliatelle: case: rules: json: snake # why it's not a `snake` by default?! yaml: snake # why it's not a `snake` by default?! xml: camel bson: camel avro: snake mapstructure: kebab # See also https://gist.github.com/cristaloleg/dc29ca0ef2fb554de28d94c3c6f6dc88 output: format: colored-line-number # I do not find this useful, parameter above already enables filepath # with a line and column. print-issued-lines: false # Must have. Easier to understand the output. print-linter-name: true # No skips, everything should be reported. uniq-by-line: false # No idea when this can be needed, maybe a multi module setup? path-prefix: "" # Slightly easier to follow the results + getting deterministic output. sort-results: true issues: # Found it strange to skip the errors, setting 0 to have all the results. max-issues-per-linter: 0 # Same here, nothing should be skipped to not miss errors. max-same-issues: 0 # When set to `true` linter will analyze only new code which are # not committed or after some specific revision. This is a cool # feature when you're going to introduce linter into a big project. # But I prefer going gradually package by package. # So, it's set to `false` to scan all code. new: false # 2 other params regarding git integration # Even with a recent GPT-4 release I still believe that # I know better how to do my job and fix the suggestions. fix: false