# Конфиг golangci-lint (схема v2; устанавливается через `task setup`). # # Базовый набор v2 (`default: standard`) — errcheck, govet, ineffassign, # staticcheck, unused. Сверх него включены линтеры, механизирующие конвенции # из docs/conventions/README.md: то, что проверяет правило, не остаётся прозой. version: "2" linters: enable: - misspell # docs/conventions/logging.md: msg — константная категория, данные — в # полях, единый стиль ключ-значение. - sloglint # docs/conventions/README.md: без fmt.Print* (логируем через slog), конфиг только # из TOML (env не используем), время — только store.Now(). - forbidigo # docs/conventions/errors.md: сравнение через errors.Is/As. - errorlint # docs/conventions/errors.md: ошибки — только stdlib. - depguard settings: sloglint: no-mixed-args: true # не мешать пары «ключ-значение» с slog.Attr kv-only: true # принятый в проекте стиль вызова static-msg: true # msg — константа, без fmt.Sprintf и интерполяции forbidigo: forbid: - pattern: ^fmt\.Print.*$ msg: логируем через slog, в stdout напрямую не пишем (docs/conventions/logging.md) - pattern: ^os\.Getenv$ msg: конфигурация только из TOML, env для конфига не используем (docs/conventions/config.md) - pattern: ^time\.Now$ msg: время генерирует store.Now() (UTC, единая точка) — docs/conventions/storage.md errorlint: # Обёртка вида fmt.Errorf("%w: %v", ErrSentinel, err) осознанна: sentinel # раскрываем для errors.Is, причину — намеренно нет. errorf: false asserts: true comparison: true depguard: rules: main: deny: - pkg: github.com/pkg/errors desc: ошибки — только stdlib errors + fmt.Errorf (docs/conventions/errors.md) - pkg: github.com/cockroachdb/errors desc: стек-трейсы избыточны, контекст несёт slog (docs/conventions/errors.md) exclusions: generated: lax presets: - comments - common-false-positives - legacy - std-error-handling paths: - third_party$ - builtin$ - examples$ # Черновое и временное живёт в ./tmp (CLAUDE.md, «Запреты»): туда же # попадают worktree батча и диагностические программы. Конвенции на них # не распространяются — иначе черновик красит гейт по причине, не # связанной с изменением, и настоящую красноту перестают читать. - ^tmp/ rules: # CLI — другая поверхность: печатает результат в stdout, это не логи. - path: ^cmd/ linters: [forbidigo] # Единая точка генерации id и времени — им time.Now по определению можно. - path: ^internal/(ident|store)/ text: time.Now linters: [forbidigo] # Замер длительности запроса — не метка времени в БД: засекается на # входе транспорта и никуда не сохраняется. - path: ^internal/httpapi/ text: time.Now linters: [forbidigo] # В тестах время задаётся явно, чтобы не зависеть от часов машины. - path: _test\.go$ text: time.Now linters: [forbidigo] formatters: exclusions: generated: lax paths: - third_party$ - builtin$ - examples$ - ^tmp/