Как устроена автоматизация и используются ли линтеры
Что проверяют
Знаете ли вы стандартный набор инструментов Go и умеете ли собрать из него проверку, которая реально блокирует плохой код. Следом часто спрашивают, какие линтеры вы включаете в golangci-lint и как внедрить его на старый проект с тысячей замечаний.
Как отвечать
Опишите слои, от встроенного к внешнему:
gofmtиgoimports: форматирование в Go одно для всех и не обсуждается. В CI проверяется, что после форматирования дифф пустой;go vet: встроенный анализатор подозрительных конструкций, например неверных аргументовPrintfили копированияsync.Mutex. Часть его проверокgo testзапускает сам;staticcheck: самый ценный внешний анализатор, ловит мёртвый код, ошибки в работе со временем и контекстом, устаревшие API;golangci-lint: агрегатор, который запускает десятки линтеров за один проход с общим кешем. Конфигурация в.golangci.yml, в стандартном набореerrcheck,govet,staticcheck,unused,ineffassign. Сверху обычно добавляютgosec,revive,bodyclose,errorlint;govulncheck: ищет известные уязвимости в зависимостях и показывает только те, что достижимы из вашего кода;- гигиена модулей:
go mod tidyиgo generateв CI с проверкой, что дифф пустой.
Команды удобно собрать в Makefile или Taskfile, чтобы локально и в CI выполнялось одно и то же. В пайплайне на каждый merge request: линт, go test -race ./..., сборка. На легаси-проекте включают --new-from-rev, тогда линтер ругается только на новый код.
Приведите свой пример: какие линтеры включали, что они поймали, сколько занимает прогон. Если на проекте этого не было, честно скажите и опишите, с чего начали бы.
Где спотыкаются
Называют golint основным линтером. Он давно объявлен устаревшим и заархивирован, его место занял revive.
Включают в golangci-lint все линтеры сразу. Получаются сотни замечаний о стиле, команда начинает массово ставить //nolint, и полезные предупреждения тонут в шуме.
Ставят //nolint без имени линтера и причины. Правильно писать //nolint:errcheck // причина, а линтер nolintlint следит, чтобы так и было.