# golangci-lint v2 configuration for mc-proxy.
# Principle: fail loudly. Security and correctness issues are errors, not warnings.

version: "2"

run:
  timeout: 5m
  # Include test files so security rules apply to test helpers too.
  tests: true

linters:
  default: none
  enable:
    # --- Correctness ---
    # Unhandled errors are silent failures; in auth code they become vulnerabilities.
    - errcheck
    # go vet: catches printf-verb mismatches, unreachable code, suspicious constructs.
    - govet
    # Detects assignments whose result is never used; dead writes hide logic bugs.
    - ineffassign
    # Detects variables and functions that are never used.
    - unused

    # --- Error handling ---
    # Enforces proper error wrapping (errors.Is/As instead of == comparisons) and
    # prevents accidental discard of wrapped sentinel errors.
    - errorlint

    # --- Security ---
    # Primary security scanner: hardcoded secrets, weak RNG, insecure crypto
    # (MD5/SHA1/DES/RC4), SQL injection, insecure TLS, file permission issues, etc.
    - gosec
    # Deep static analysis: deprecated APIs, incorrect mutex use, unreachable code,
    # incorrect string conversions, simplification suggestions, and hundreds of other checks.
    # (gosimple was merged into staticcheck in golangci-lint v2)
    - staticcheck

    # --- Style / conventions (per CLAUDE.md) ---
    # Enforces Go naming conventions and selected style rules.
    - revive

  settings:
    errcheck:
      # Do NOT flag blank-identifier assignments: `_ = rows.Close()` in defers,
      # `_ = tx.Rollback()` after errors, and `_ = fs.Parse(args)` with ExitOnError
      # are all legitimate patterns where the error is genuinely unrecoverable or
      # irrelevant. The default errcheck (without check-blank) still catches
      # unchecked returns that have no assignment at all.
      check-blank: false
      # Flag discarded ok-value in type assertions: `c, _ := x.(*T)` — the ok
      # value should be checked so a failed assertion is not silently treated as nil.
      check-type-assertions: true

    govet:
      # Enable all analyzers except shadow. The shadow analyzer flags the idiomatic
      # `if err := f(); err != nil { ... }` pattern as shadowing an outer `err`,
      # which is ubiquitous in Go and does not pose a security risk in this codebase.
      enable-all: true
      disable:
        - shadow

    gosec:
      # Treat all gosec findings as errors, not warnings.
      severity: medium
      confidence: medium
      excludes:
        # G104 (errors unhandled) overlaps with errcheck; let errcheck own this.
        - G104

    errorlint:
      errorf: true
      asserts: true
      comparison: true

    revive:
      rules:
        # error-return and unexported-return are correctness/API-safety rules.
        - name: error-return
          severity: error
        - name: unexported-return
          severity: error
        # Style rules.
        - name: error-strings
          severity: warning
        - name: if-return
          severity: warning
        - name: increment-decrement
          severity: warning
        - name: var-naming
          severity: warning
        - name: range
          severity: warning
        - name: time-naming
          severity: warning
        - name: indent-error-flow
          severity: warning
        - name: early-return
          severity: warning
        # exported and package-comments are omitted: this is a personal project,
        # not a public library; godoc completeness is not a CI requirement.

formatters:
  enable:
    # Enforces gofmt formatting. Non-formatted code is a CI failure.
    - gofmt
    # Manages import grouping and formatting; catches stray debug imports.
    - goimports

issues:
  # Do not cap the number of reported issues; in security code every finding matters.
  max-issues-per-linter: 0
  max-same-issues: 0

  exclusions:
    paths:
      - vendor
    rules:
      # In test files, allow hardcoded test credentials (gosec G101) since they are
      # intentional fixtures, not production secrets.
      - path: "_test\\.go"
        linters:
          - gosec
        text: "G101"

