Запуск нескольких линтеров 3. Как запускать линтеры pkgs = $(shell go list ./... | fgrep -v /vendor) lint: go get golang.org/x/lint/golint go get honnef.co/go/tools/cmd/staticcheck go get github.com/kisielk/errcheck golint $(pkgs) go vet $(pkgs) staticcheck $(pkgs) errcheck $(pkgs) Makefile для запуска 4-х линтеров
Параллельный запуск 3. Как запускать линтеры pkgs = $(shell go list ./... | fgrep -v /vendor) lint: go get golang.org/x/lint/golint go get honnef.co/go/tools/cmd/staticcheck go get github.com/kisielk/errcheck echo $(pkgs) | xargs -P4 golint echo $(pkgs) | xargs -P4 go vet echo $(pkgs) | xargs -P4 staticcheck echo $(pkgs) | xargs -P4 errcheck
Больше скорости. Build cache 3. Как запускать линтеры $ go clean -cache $ time golangci-lint run --fast real 0m17.533s $ time golangci-lint run --fast real 0m6.585s
Незначимые сообщения от линтеров 4. Внедрение в проект cache.go:7:6: exported type Cache should have comment or be unexported redis.go:13:6: exported type Redis should have comment or be unexported redis.go:17:1: exported function NewRedis should have comment or be unexported redis.go:33:1: exported method Redis.Get should have comment or be unexported redis.go:55:1: exported method Redis.Set should have comment or be unexported
Исключаем неважные для нас сообщения 4. Внедрение в проект # .golangci.yml issues: exclude: - should have comment or be unexported - another pattern Опция `exclude` исключает сообщения по их тексту по регулярке golangci-lint автоматически находит .golangci.yml
Исключаем по путям 4. Внедрение в проект # .golangci.yml run: skip-dirs: - pkg/examples skip-files: - ".*\\.generated\\.go$" golangci-lint автоматически исключает сгенерированны е файлы
Исключаем конкретные случаи 4. Внедрение в проект var bad_name int //nolint:golint var b_a_d int //nolint:golint,gofmt var v int //nolint //nolint:prealloc func f() { // ... } Можно исключать текущую строку или блок //nolint
Незначимые сообщения от линтеров 4. Внедрение в проект package logutils import ( "fmt" "os" "github.com/sirupsen/logrus" //nolint:depguard ) #https://github.com/golangci/golangci-lint/blob/master /pkg/logutils/stderr_log.go#L7
Нет времени исправлять тонну проблем 4. Внедрение в проект $ go vet main.go:5: missing argument for Sprintf("%s") main.go:6: missing argument for Sprintf("%s")
Нет времени исправлять тонну проблем 4. Внедрение в проект $ go vet main.go:5: missing argument for Sprintf("%s") main.go:6: missing argument for Sprintf("%s") $ go vet |& revgrep origin/master main.go:6: missing argument for Sprintf("%s")
Добавление нового линтера 4. Внедрение в проект $ golangci-lint run $ golangci-lint run \ --disable-all \ --enable newlinter --new-from-rev=origin/master
Воспроизводимость в CI 5. Удобство работы go get github.com/some/linter wget -O - -q \ https://github.com/some/linter/install.sh | sh -s v1.2.3 golangci-lint run --enable-all golangci-lint run --disable-all -Eerrcheck -E...
Кратко как применить доклад 1. Попробуйте включить все линтеры в golangci-lint 2. Встройте golangci-lint в CI + IDE + pre-commit 3. Примените --new-from-rev для быстрой интеграции 4. Сделайте линтеры ревьюерами через Reviewdog/CodeClimate.com/GolangCI.com/...
Темы для дальнейшего обсуждения 1. Настройка .golangci.yml 2. Go/analysis и дальнейшее развитие линтеров 3. Разработка своего линтера 4. Страдания с gocyclo