Инструментарий

Что это такое

Go поставляется вместе с командами, которых проекту достаточно: форматтер с единственно верной разметкой, сборщик статических бинарных файлов, запуск тестов, управление зависимостями и сервер документации. Всё это — часть дистрибутива языка, а не отдельные инструменты, которые каждая команда выбирает сама, поэтому любой проект на Go собирается, форматируется и тестируется одним и тем же способом.

Почему это важно

Там, где выбор убран, не остаётся ни споров, ни настройки. Спорить о форматировании не приходится, поскольку форматтер практически не настраивается; выбирать средство сборки — тоже, потому что сборщик один; фреймворк для тестов не выбирают, потому что в стандартной библиотеке есть свой. По кодовой базе это заметно: незнакомый код на Go читается легко, а новый участник собирает и запускает проект, не открывая руководство по настройке. Однако у удобства есть цена — жёсткость, а также намеренно бедная работа с зависимостями по сравнению с другими экосистемами. Команде, которой действительно нужен другой рабочий процесс, здесь тесно.

Ключевые идеи

Форматирование — не решение

Форматтер переписывает файл в каноническую разметку, причём один и тот же инструмент запускают и редакторы, и проверки непрерывной интеграции. Вывод детерминирован, поэтому в диффе не смешиваются изменение форматирования и изменение поведения. Здесь яснее всего видно, что язык предпочитает одно навязанное решение множеству разумных.

go fmt ./...      -> переписывает файлы в каноническую разметку

Сборка даёт самодостаточный бинарный файл

Компиляция сводит все зависимости в один исполняемый файл, которому не нужна внешняя среда выполнения. Кросс-компиляцию под другую операционную систему или архитектуру задают в команде, а не отдельным инструментарием: поэтому с одной машины выпуск может собрать бинарные файлы сразу для нескольких платформ.

Зависимости объявлены и зафиксированы с проверкой целостности

Модуль объявляет свои зависимости и их версии, а отдельный файл хранит точные версии и криптографические хеши того набора, который получился при разрешении. Пока этот файл на месте, сборка воспроизводит один и тот же набор зависимостей на любой машине, а несовпадение хеша скачанного модуля её останавливает. Версии разрешаются по правилу минимальной версии, поэтому опубликованная библиотекой новинка не обновляет сборку молча.

Тестирование — часть инструментария, а бенчмарки повторяют его форму

Тесты лежат в том же пакете, что и код, запускаются одной командой и по запросу сообщают покрытие. Бенчмарки используют тот же механизм, только с другим префиксом, так что измерение и тестирование — один рабочий процесс. А поскольку в стандартной библиотеке есть и HTTP-клиент, и сервер, интеграционный тест обходится без сторонних помощников.

Сборка под развёртывание — явная цель

Собирать можно под другую операционную систему и архитектуру, а отладочную информацию — опустить, чтобы файл получился меньше. На выходе один артефакт: его копируют в минимальный образ контейнера, где больше ничего нет, поэтому такие образы часто бывают поразительно малы.

Стандартная библиотека — зависимость по умолчанию

HTTP-сервер, поддержка JSON, криптографические примитивы, средство тестирования — всё уже включено. Сторонний пакет стоит брать осознанно: каждый добавляет версию в сопровождение и поверхность для отслеживания уязвимостей.

Практика

Соберите под другую платформу

Возьмите небольшую программу, получите бинарный файл для другой операционной системы и архитектуры и запустите его в окружении такого рода.

Готово, когда: бинарный файл запускается без установленной среды выполнения, и вы можете назвать две настройки, которые его создали.

Воспроизведите набор зависимостей

Соберите проект с несколькими зависимостями, а затем соберите его снова — без сети, но с кэшем модулей на месте.

Готово, когда: вторая сборка проходит на одних только записанных версиях и их хешах целостности.

Частые ошибки

  • Борьба с форматтером — разметка не настраивается, и спор потрачен впустую; исправить: запустите его и зафиксируйте результат.
  • Обращение к стороннему пакету за тем, что есть в стандартной библиотеке — лишнее сопровождение и поверхность для уязвимостей; исправить: сначала проверьте стандартную библиотеку.
  • Ручное редактирование файла с записанными зависимостями — хеши целостности перестают совпадать; исправить: измените объявление и позвольте инструменту обновить запись.
  • Игнорирование целевой платформы до самого выпуска — сборка, работающая локально, падает на архитектуре развёртывания; исправить: собирайте под целевую платформу в составе конвейера.
  • Уверенность, что новая версия подхватывается автоматически — правило минимальной версии намеренно этого не делает; исправить: обновляйте зависимости осознанно.

Что читать дальше

  • Go (05-backend-data/05-go) — язык, которому принадлежит этот инструментарий, поэтому начните с него.
  • Конкурентность (05-backend-data/05-go/02-concurrency) — возможность языка, под которую спроектирован инструментарий.
  • Docker (06-cloud-devops/06-docker) — где упаковывается тот единственный статический бинарный файл, который создаёт этот инструментарий.