Files
transcriber/.golangci.yml
T
av 35bde75b1f Гейт роняет проверку, судящую ответ по живой карте заголовков
- forbidigo с analyze-types запрещает в файлах проверок обращение к
  httptest.ResponseRecorder.Header и .HeaderMap: правило судит по типу
  приёмника, поэтому ловит и цепочку, и переменную, и индекс, и обход
- класс стоил трёх зелёных гейтов при неработающем коде; правило записано
  строкой в перечне механизированного, прозой не дублируется
- поправлены два утверждения «механизировано: ничего», разошедшиеся с
  включённым линтером и со сверкой шага схемы
2026-08-12 22:04:35 +03:00

68 lines
4.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
version: "2"
linters:
default: standard
enable:
- errorlint
- forbidigo
settings:
forbidigo:
# Проверка ответа судит по **готовому ответу**, а не по изменяемому
# состоянию обработчика. `httptest` устроен зеркально настоящему серверу:
# `Header()` отдаёт живую карту, доступную и после записи ответа, а снимок,
# который получит клиент, лежит отдельно и читается через `Result()`.
# Проверка, читающая живую карту, зелена при неработающем коде — класс
# всплывал трижды (docs/review.md, записи 2026-08-10, 2026-08-11 и
# 2026-08-12) и трижды стоил зелёного гейта.
#
# Правило действует только в `*_test.go` — исключение ниже: в самом
# обработчике `Header()` и есть способ отдать заголовок.
#
# Судит оно **по типу приёмника**, а не по печатному тексту вызова
# (`analyze-types`), и в этом весь смысл: запрет на цепочку
# `w.Header().Get` обходится одной лишней строкой — `h := w.Header()`, —
# а также чтением по индексу карты и обходом `range`. По типу под правило
# попадают все эти формы разом. Записать его текстом нельзя ещё и потому,
# что `.Header` носят и запрос (`req.Header.Set` в проверках законен), и
# снимок ответа (`w.Result().Header` — как раз то, к чему правило ведёт).
#
# Приёмник назван поимённо: подставной сервер в проверках отдаёт заголовок
# через `w.Header().Set`, но у него приёмник — `http.ResponseWriter`, и под
# правило он не попадает.
#
# `HeaderMap` — тот же живой снимок прежним именем поля; правило второе,
# потому что о его устарелости говорит `staticcheck` (SA1019), а о том,
# почему по нему не судят ответ, — только это сообщение.
analyze-types: true
forbid:
- pattern: '^httptest\.ResponseRecorder\.Header$'
msg: 'проверка судит ответ по живой карте заголовков: читай w.Result().Header'
- pattern: '^httptest\.ResponseRecorder\.HeaderMap$'
msg: 'проверка судит ответ по живой карте заголовков: читай w.Result().Header'
errcheck:
# Без этого `_ = x.Close()` снимает замечание, и критерий «отказ не
# теряется молча» принимается реализацией, которая его теряет. Отказ,
# который решено не проверять, теперь объявляют ниже поимённо — заметно.
check-blank: true
exclude-functions:
# Закрытие через defer и лучшая-попытка уборки файла — осознанно без проверки
- (io.Closer).Close
- (*database/sql.DB).Close
- (*os.File).Close
- (io.ReadCloser).Close
- os.Remove
# Метод сам логирует ошибку отправки, вызывающему она не нужна
- (*git.vakhrushev.me/av/transcriber/internal/controller/tg.TelegramController).send
exclusions:
rules:
# `path-except` оставляет находки только в файлах проверок: в рабочем коде
# чтение своей карты заголовков законно.
- linters:
- forbidigo
path-except: '_test\.go$'
formatters:
enable:
- gofmt