run:
  timeout: 20m

linters:
  enable:
    - errcheck
    - forbidigo
    - gci
    - gofmt
    - gofumpt
    - gosimple
    - govet
    - ineffassign
    - lll
    - loggercheck
    - misspell
    - revive
    - unused
    - usestdlibvars
    - wsl

  disable:
    # Consumes a large amount of memory when running with Graph SDK in the
    # project causing OOM failures in Github actions.
    - staticcheck

linters-settings:
  gci:
    sections:
      - standard
      - default
      - prefix(github.com/alcionai/corso)
    skip-generated: true
  forbidigo:
    forbid:
      # Don't allow creating contexts without logging in tests. Use an ignore
      # lower down to ensure usages of this outside of tests aren't reported.
      - 'context\.(Background|TODO)(# tests should use tester\.NewContext)?'
      # Don't allow use of path as it hardcodes separator to `/`.
      # Use filepath instead.
      - '\bpath\.(Ext|Base|Dir|Join)'
      # Don't allow the typo m356 to be used in place of m365.
      - '[Mm]356(# typo: should be 365)?'
      # Don't allow use of testify suite directly. Use one of the wrappers from
      # tester/suite.go instead. Use an ignore lower down to exclude packages
      # that result in import cycles if they try to use the wrapper.
      - 'suite\.Suite(# tests should use one of the Suite wrappers in tester package)?'
      # All errors should be constructed and wrapped with the clues package.
      # String formatting should be avoided in favor of structured errors (ie: err.With(k, v)).
      - '(errors|fmt)\.(New|Stack|Wrap|Error)f?\((# error handling should use clues pkg)?'
      # Avoid Warn-level logging in favor of Info or Error.
      - 'Warn[wf]?\((# logging should use Info or Error)?'
      # Prefer suite.Run(name, func() {}) for subtests as testify has it instead
      # of suite.T().Run(name, func(t *testing.T) {}).
      - '(T\(\)|\st[a-zA-Z0-9]*)\.Run(# prefer testify suite.Run(name, func()) )?'
  lll:
    line-length: 120
  revive:
    max-open-files: 2048
    # Don't know why, but false means ignore generated files.
    ignore-generated-header: false
    rules:
      - name: blank-imports
      - name: bool-literal-in-expr
      - name: constant-logical-expr
      - name: context-as-argument
      - name: context-keys-type
      - name: duplicated-imports
      - name: early-return
      - name: empty-block
      - name: errorf
      - name: error-naming
      - name: error-return
      - name: error-strings
      - name: exported
      - name: identical-branches
      - name: if-return
      - name: import-shadowing
      - name: increment-decrement
      - name: indent-error-flow
      - name: modifies-value-receiver
      - name: package-comments
      - name: range
      - name: receiver-naming
      - name: redefines-builtin-id
      - name: superfluous-else
      - name: time-equal
      - name: time-naming
      - name: unreachable-code
      - name: use-any
      - name: useless-break
      - name: var-declaration
      - name: var-naming

issues:
  # Limit on number of errors with identical text reported.
  max-same-issues: 50
  exclude-rules:
    - linters:
        - revive
      text: "exported:.*details.DetailsModel by other packages, and that stutters"
    - linters:
        - revive
      text: "exported:.*details.DetailsEntry by other packages, and that stutters"
    - linters:
        - revive
      text: "exported:.*mock.MockModelStore by other packages, and that stutters"
    - linters:
        - revive
      text: "unexported-return:.*unexported type selectors.exchangeCategory"
    - linters:
        - revive
      text: "unexported-return:.*unexported type.*kopia.conn"
    - path: _test\.go
      linters:
        - revive
      text: "import-shadowing:.*'suite' shadows"
    # Don't output about context.Background or context.TODO in non-test files.
    # Need complicated multi-part regex because golang doesn't support not regex
    # operators for sequences of characters (only character sets). The below
    # basically boils down to:
    #   1. anything 4 characters long with .go suffix
    #   2. anything >= 5 characters long that doesn't end in _test.go
    - path: ^.{4}\.go|.*([^_].{4}|_[^t].{3}|_t[^e].{2}|_te[^s].{1}|_tes[^t])\.go
      linters:
        - forbidigo
      text: "context.(Background|TODO)"
    - path: internal/m365/graph/betasdk
      linters:
        - wsl
        - revive
        - gci
        - lll
        - gofmt
        - gofumpt
        - misspell
        - errcheck
        - forbidigo
    - path: internal/tester/suite.go
      linters:
        - forbidigo
      text: "suite.Suite"
    # account package creates an import cycle with tester package.
    - path: pkg/account
      linters:
        - forbidigo
      text: "suite.Suite"
    # storage package creates an import cycle with tester package.
    - path: pkg/storage
      linters:
        - forbidigo
      text: "suite.Suite"
    # Not yet updated. Unclear if it should be updated.
    - path: pkg/repository/loadtest
      linters:
        - forbidigo
      text: "suite.Suite"
