Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Как готовить линтеры в Go – Денис Исаев

Как готовить линтеры в Go – Денис Исаев

GopherCon Russia

April 13, 2019
Tweet

More Decks by GopherCon Russia

Other Decks in Programming

Transcript

  1. 1. Зачем нужны линтеры 2. 50+ линтеров: какие использовать 3.

    Запуск линтеров 4. Внедрение в проект 5. Удобство работы Содержание
  2. Почему линтеры не используют 1. Зачем нужны линтеры “Линтеры только

    замедляют разработку, и их долго настраивать”
  3. Почему линтеры не используют 1. Зачем нужны линтеры “Они находят

    только всякую мелочь, ничего серьезного”
  4. { Выводы Линтеры 1. Находить критичные баги 2. Находить баги

    рано 3. Ускорять код-ревью 4. Гарантировать качество кода 1. Зачем нужны линтеры
  5. Запуск нескольких линтеров 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-х линтеров
  6. Параллельный запуск 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
  7. Go Meta Linter 3. Как запускать линтеры $ gometalinter \

    --disable-all \ --enable golint --enable vet \ --enable staticcheck \ --enable errcheck \ --deadline=1m \ --vendor \ ./...
  8. Плюшки golangci-lint 3. Как запускать линтеры 1. Производительность 2. Удобная

    yaml конфигурация 3. Фильтрация предупреждений: --skip-dirs, --exclude 4. Исключения предупреждений в коде: //nolint
  9. Больше скорости. --fast 3. Как запускать линтеры $ golangci-lint help

    linters | fgrep "fast: false" 1. staticcheck 2. unused 3. gosimple 4. stylecheck 5. interfacer 6. unparam
  10. Больше скорости. Build cache 3. Как запускать линтеры $ go

    clean -cache $ time golangci-lint run --fast real 0m17.533s $ time golangci-lint run --fast real 0m6.585s
  11. Больше скорости. Build cache в CI 3. Как запускать линтеры

    # .travis.yml cache: directories: - $HOME/.cache/go-build - $HOME/gopath/pkg/mod
  12. Незначимые сообщения от линтеров 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
  13. Исключаем неважные для нас сообщения 4. Внедрение в проект #

    .golangci.yml issues: exclude: - should have comment or be unexported - another pattern Опция `exclude` исключает сообщения по их тексту по регулярке golangci-lint автоматически находит .golangci.yml
  14. Исключаем по путям 4. Внедрение в проект # .golangci.yml run:

    skip-dirs: - pkg/examples skip-files: - ".*\\.generated\\.go$" golangci-lint автоматически исключает сгенерированны е файлы
  15. Исключаем конкретные случаи 4. Внедрение в проект var bad_name int

    //nolint:golint var b_a_d int //nolint:golint,gofmt var v int //nolint //nolint:prealloc func f() { // ... } Можно исключать текущую строку или блок //nolint
  16. Незначимые сообщения от линтеров 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
  17. Нет времени исправлять тонну проблем 4. Внедрение в проект $

    go vet main.go:5: missing argument for Sprintf("%s") main.go:6: missing argument for Sprintf("%s")
  18. Нет времени исправлять тонну проблем 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")
  19. Нет времени исправлять тонну проблем 4. Внедрение в проект $

    golangci-lint run \ --new-from-rev=origin/master $ golangci-lint run --new
  20. Добавление нового линтера 4. Внедрение в проект $ golangci-lint run

    $ golangci-lint run \ --disable-all \ --enable newlinter --new-from-rev=origin/master
  21. Воспроизводимость в 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...
  22. Pre-commit hook 5. Удобство работы # .pre-commit-config.yaml repos: - repo:

    https://github.com/golangci/golangci-lint rev: v1.16.0 hooks: - id: golangci-lint # pip install pre-commit # pre-commit install
  23. 1. Зачем нужны линтеры 2. 50+ линтеров: какие использовать 3.

    Запуск линтеров 4. Внедрение в проект 5. Удобство работы Что мы обсудили
  24. Кратко как применить доклад 1. Попробуйте включить все линтеры в

    golangci-lint 2. Встройте golangci-lint в CI + IDE + pre-commit 3. Примените --new-from-rev для быстрой интеграции 4. Сделайте линтеры ревьюерами через Reviewdog/CodeClimate.com/GolangCI.com/...
  25. Темы для дальнейшего обсуждения 1. Настройка .golangci.yml 2. Go/analysis и

    дальнейшее развитие линтеров 3. Разработка своего линтера 4. Страдания с gocyclo