# This file is licensed under the terms of the MIT license https://opensource.org/license/mit # Copyright (c) 2021-2025 Marat Reymers ## Golden config for golangci-lint v2.1.2 # # 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 it to suit your needs. # If this config helps you, please consider keeping a link to this file (see the next comment). # Based on https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322 version: "2" issues: # Maximum count of issues with the same text. # Set to 0 to disable. # Default: 3 max-same-issues: 50 formatters: enable: - goimports # checks if the code and import statements are formatted according to the 'goimports' command - golines # checks if code is formatted, and fixes long lines ## you may want to enable #- gci # checks if code and import statements are formatted, with additional rules #- gofmt # checks if the code is formatted according to 'gofmt' command ## disabled #- gofumpt # [replaced by goimports, gofumports is not available yet] checks if code and import statements are formatted, with additional rules # All settings can be found here https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.reference.yml settings: goimports: # A list of prefixes, which, if set, checks import paths # with the given prefixes are grouped after 3rd-party packages. # Default: [] local-prefixes: - github.com/my/project golines: # Target maximum line length. # Default: 100 max-len: 120 linters: enable: - 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 - depguard # checks if package imports are in a list of acceptable packages - dupl # tool for code clone detection - durationcheck # checks for two durations multiplied together - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases - 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 - exptostd # detects functions from golang.org/x/exp/ that can be replaced by std functions - fatcontext # detects nested contexts in loops - forbidigo # forbids identifiers - funcorder # checks the order of functions, methods, and constructors - 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 - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod - goprintffuncname # checks that printf-like functions are named with f at the end - gosec # inspects source code for security problems - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string - iface # checks the incorrect use of interfaces, helping developers avoid interface pollution - ineffassign # detects when assignments to existing variables are not used - intrange # finds places where for loops could make use of an integer range - 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 - misspell # finds commonly misspelled English words in comments - 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 - nilnesserr # reports that it checks for err != nil, but it returns a different nil value error (powered by nilness and nilerr) - 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 - staticcheck # is a go vet on steroids, applying a ton of static analysis checks - 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 - unused # checks for unused constants, variables, functions and types - usestdlibvars # detects the possibility to use variables/constants from the Go standard library - usetesting # reports uses of functions with replacement inside the testing package - 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 #- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega #- godox # detects usage of FIXME, TODO and other keywords inside comments #- 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 #- 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 #- forcetypeassert # [replaced by errcheck] finds forced type assertions #- gomodguard # [use more powerful depguard] allow and block lists linter for direct Go module dependencies #- gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase #- grouper # analyzes expression groups #- importas # enforces consistent import aliases #- lll # [replaced by golines] reports long lines #- maintidx # measures the maintainability index of each function #- 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 # All settings can be found here https://github.com/golangci/golangci-lint/blob/HEAD/.golangci.reference.yml 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 depguard: # Rules to apply. # # Variables: # - File Variables # Use an exclamation mark `!` to negate a variable. # Example: `!$test` matches any file that is not a go test file. # # `$all` - matches all go files # `$test` - matches all go test files # # - Package Variables # # `$gostd` - matches all of go's standard library (Pulled from `GOROOT`) # # Default (applies if no custom rules are defined): Only allow $gostd in all files. rules: "deprecated": # List of file globs that will match this list of settings to compare against. # By default, if a path is relative, it is relative to the directory where the golangci-lint command is executed. # The placeholder '${base-path}' is substituted with a path relative to the mode defined with `run.relative-path-mode`. # The placeholder '${config-path}' is substituted with a path relative to the configuration file. # Default: $all files: - "$all" # List of packages that are not allowed. # Entries can be a variable (starting with $), a string prefix, or an exact match (if ending with $). # Default: [] deny: - pkg: github.com/golang/protobuf desc: Use google.golang.org/protobuf instead, see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules - pkg: github.com/satori/go.uuid desc: Use github.com/google/uuid instead, satori's package is not maintained - pkg: github.com/gofrs/uuid$ desc: Use github.com/gofrs/uuid/v5 or later, it was not a go module before v5 "non-test files": files: - "!$test" deny: - pkg: math/rand$ desc: Use math/rand/v2 instead, see https://go.dev/blog/randv2 "non-main files": files: - "!**/main.go" deny: - pkg: log$ desc: Use log/slog instead, see https://go.dev/blog/slog 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$ funcorder: # Checks if the exported methods of a structure are placed before the non-exported ones. # Default: true struct-method: false 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 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 found at https://go-critic.com/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 govet: # Enable all analyzers. # Default: false enable-all: true # Disable analyzers by name. # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled 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, golines ] # 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 reassign: # Patterns for global variable names that are checked for reassignment. # See https://github.com/curioswitch/go-reassign#usage # Default: ["EOF", "Err.*"] patterns: - ".*" 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 staticcheck: # SAxxxx checks in https://staticcheck.dev/docs/configuration/options/#checks # Example (to disable some checks): [ "all", "-SA1000", "-SA1001"] # Default: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"] checks: - all # Incorrect or missing package comment. # https://staticcheck.dev/docs/checks/#ST1000 - -ST1000 # Use consistent method receiver names. # https://staticcheck.dev/docs/checks/#ST1016 - -ST1016 # Omit embedded fields from selector expression. # https://staticcheck.dev/docs/checks/#QF1008 - -QF1008 usetesting: # Enable/disable `os.TempDir()` detections. # Default: false os-temp-dir: true exclusions: # Log a warning if an exclusion rule is unused. # Default: false warn-unused: true # Predefined exclusion rules. # Default: [] presets: - std-error-handling - common-false-positives # Excluding configuration per-path, per-linter, per-text and per-source. rules: - source: 'TODO' linters: [ godot ] - text: 'should have a package comment' linters: [ revive ] - text: 'exported \S+ \S+ should have comment( \(or a comment on this block\))? or be unexported' linters: [ revive ] - text: 'package comment should be of the form ".+"' source: '// ?(nolint|TODO)' linters: [ revive ] - text: 'comment on exported \S+ \S+ should be of the form ".+"' source: '// ?(nolint|TODO)' linters: [ revive, staticcheck ] - path: '_test\.go' linters: - bodyclose - dupl - errcheck - funlen - goconst - gosec - noctx - wrapcheck