---
version: "2"

run:
  timeout: 5m
  issues-exit-code: 1

linters:
  enable:
    - errcheck      # check error returns
    - govet         # suspicious constructs
    - staticcheck   # advanced static analysis (absorbs gosimple in v2)
    - unused        # unused code
    - ineffassign   # useless assignments
    - misspell      # spelling mistakes
    - gocritic      # opinionated lints
    - revive        # replacement for golint
    - unconvert     # unnecessary type conversions
    - bodyclose     # http response body not closed
    - noctx         # http requests without context
    - gosec         # security issues
    - errorlint     # error wrapping and comparison
    - nilnil        # return nil, nil
    - wastedassign  # assignments to variables never read
    - usetesting    # os.Setenv in tests instead of t.Setenv, etc.

  settings:
    govet:
      enable-all: true
      disable:
        # too many structs to reorder, risks breaking serialization
        - fieldalignment
        - shadow          # common Go pattern, too noisy
        - unusedwrite     # false positives on test data structs
    errcheck:
      check-blank: false
      exclude-functions:
        # log writes are best-effort
        - github.com/dropalldatabases/sif/internal/logger.Write
        # Close on io.Closer is idiomatic best-effort
        - (io.Closer).Close
        - (*os.File).Close
        - (*net/http.Response).Body.Close
        # fmt.Fprint* returns are rarely actionable
        - fmt.Fprint
        - fmt.Fprintf
        - fmt.Fprintln
    staticcheck:
      # QF1003/QF1012 are v2 quickfix suggestions, not bugs.
      # ST1000/ST1003 were the stylecheck linter in v1
      # (not previously enabled); skipping to match prior parity.
      checks:
        - all
        - -QF1003
        - -QF1012
        - -ST1000
        - -ST1003
    revive:
      rules:
        # stuttering names (scan.ScanResult) need breaking API changes
        - name: exported
          disabled: true
    gocritic:
      enabled-tags:
        - diagnostic
        - style
        - performance
      disabled-checks:
        - commentedOutCode   # too opinionated for a project with TODOs
        - paramTypeCombine   # style-only, not worth churn
        - unnamedResult      # style-only
        - unnecessaryDefer   # common pattern in tests
        # inverting conditions in scan logic hurts readability
        - nestingReduce
    gosec:
      excludes:
        - G104  # errcheck covers this
        - G107  # pentesting tool -- variable URLs are the whole point
        - G110  # nuclei template decompression, acceptable context
        - G304  # sif reads user-supplied wordlist paths -- intentional
        - G305  # tar extraction is traversal-guarded (HasPrefix on the
                # cleaned target); gosec flags filepath.Join regardless

  exclusions:
    rules:
      # test files get some slack
      - path: _test\.go
        linters:
          - errcheck
          - noctx
          - gosec  # fake credentials in secret-scanner fixtures are not real keys
          - bodyclose  # synthetic *http.Response fixtures carry no socket to close

issues:
  max-issues-per-linter: 50
  max-same-issues: 50
