version: "2"

run:
  allow-parallel-runners: true

  # timeout for analysis, e.g. 30s, 5m, default is 1m
  timeout: 5m

  # exit code when at least one issue was found, default is 1
  issues-exit-code: 1
  tests: true

linters:
  disable:
    - staticcheck
  enable:
    - sloglint
    - bodyclose
    - copyloopvar
    - depguard
    - errcheck
    - errorlint
    - gocheckcompilerdirectives
    - gocritic
    - godox
    - goprintffuncname
    - gosec
    - govet
    - intrange
    - ineffassign
    - misspell
    - noctx
    - nolintlint
    - revive
    - staticcheck
    - testifylint
    - unconvert
    - unparam
    - unused
    - whitespace
    - gocyclo
    - funlen
    - goconst
    - dogsled
    - lll

  settings:
    dogsled:
      max-blank-identifiers: 3

    gosec:
      excludes:
        - G109
        - G115
        - G204
        - G303

    sloglint:
      no-mixed-args: true
      kv-only: true
      attr-only: false
      no-global: ""
      context: ""
      static-msg: false
      no-raw-keys: true
      key-naming-case: camel
      forbidden-keys:
        - time
        - level
        - msg
        - source
      args-on-sep-lines: false

    depguard:
      rules:
        logger:
          deny:
            # logging is allowed only by logutils.Log,
            - pkg: "github.com/sirupsen/logrus"
              desc: logging is allowed only by logutils.Log.
            - pkg: "github.com/pkg/errors"
              desc: Should be replaced by standard lib errors package.
            - pkg: "github.com/instana/testify"
              desc: It's a fork of github.com/stretchr/testify.
          files:
            - "!**/pkg/logutils/**.go"

    dupl:
      threshold: 100

    funlen:
      lines: -1
      statements: 60

    goconst:
      min-len: 2
      min-occurrences: 3
      ignore-string-values:
        - blee
        - duh
        - cl-1
        - ct-1-1

    gocritic:
      enabled-tags:
        - diagnostic
        - experimental
        - opinionated
        - performance
        - style
      disabled-checks:
        - dupImport # https://github.com/go-critic/go-critic/issues/845
        - ifElseChain
        - octalLiteral
        - whyNoLint

    gocyclo:
      min-complexity: 35

    godox:
      keywords:
        - FIXME

    mnd:
      checks:
        - argument
        - case
        - condition
        - return
      ignored-numbers:
        - '0'
        - '1'
        - '2'
        - '3'
      ignored-functions:
        - strings.SplitN

    govet:
      settings:
        printf:
          funcs:
            - (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Infof
            - (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Warnf
            - (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Errorf
            - (github.com/golangci/golangci-lint/v2/pkg/logutils.Log).Fatalf
      enable:
        - nilness
        - shadow

    errorlint:
      asserts: false

    lll:
      line-length: 170

    misspell:
      locale: US
      ignore-rules:
        - "importas"

    nolintlint:
      allow-unused: false
      require-explanation: false
      require-specific: true

    revive:
      rules:
        - name: indent-error-flow
        - name: unexported-return
          disabled: true
        - name: unused-parameter
        - name: unused-receiver

  exclusions:
    presets:
      - comments
      - std-error-handling
      - common-false-positives
      - legacy
    paths:
      - test/testdata_etc # test files
      - internal/go # extracted from Go code
      - internal/x # extracted from x/tools code
      - pkg/goformatters/gci/internal # extracted from gci code
      - pkg/goanalysis/runner_checker.go # extracted from x/tools code
    rules:
      - path: (.+)_test\.go
        linters:
          - dupl
          - mnd
          - lll

      # Based on existing code, the modifications should be limited to make maintenance easier.
      - path: pkg/golinters/unused/unused.go
        linters: [gocritic]
        text: "rangeValCopy: each iteration copies 160 bytes \\(consider pointers or indexing\\)"

      # Related to the result of computation but divided multiple times by 1024.
      - path: test/bench/bench_test.go
        linters: [gosec]
        text: "G115: integer overflow conversion uint64 -> int"

      # The files created during the tests don't need to be secured.
      - path: scripts/website/expand_templates/linters_test.go
        linters: [gosec]
        text: "G306: Expect WriteFile permissions to be 0600 or less"

      # Related to migration command.
      - path: pkg/commands/internal/migrate/two/
        linters:
          - lll

      # Related to migration command.
      - path: pkg/commands/internal/migrate/
        linters:
          - gocritic
        text: "hugeParam:"

      # The codes are close but this is not duplication.
      - path: pkg/commands/(formatters|linters).go
        linters:
          - dupl

formatters:
  enable:
    - gci
    - gofmt
    - goimports
  settings:
    gofmt:
      rewrite-rules:
        - pattern: 'interface{}'
          replacement: 'any'
    goimports:
      local-prefixes:
        - github.com/golangci/golangci-lint/v2
  exclusions:
    paths:
      - test/testdata_etc # test files
      - internal/go # extracted from Go code
      - internal/x # extracted from x/tools code
      - pkg/goformatters/gci/internal # extracted from gci code
      - pkg/goanalysis/runner_checker.go # extracted from x/tools code
