5. go install и установка CLI

Если go build создает бинарник "здесь и сейчас", а go run запускает его "на лету", то go install — это команда для внедрения вашего (или чужого) инструмента в систему. Это способ превратить исходный код на Go в постоянную утилиту командной строки, доступную из любого места терминала.

Для разработчиков, переходящих с npm install -g или pip install, концепция go install покажется знакомой, но с важными нюансами, касающимися версионирования, hermeticity (герметичности) и изоляции от зависимостей текущего проекта.


Что делает go install?

По своей сути, go install очень похож на go build. Она компилирует пакеты (используя тот же кэш и компилятор). Однако у неё есть два критических отличия:

  1. Назначение: Она сохраняет скомпилированный бинарник в специальную директорию $GOBIN (или $GOPATH/bin, если GOBIN не задан), а не в текущую рабочую директорию.
  2. Сборка библиотек: Для пакетов библиотек (не main) в режиме модулей go install компилирует код и обновляет централизованный кэш сборки GOCACHE (исторически в режиме GOPATH объектные файлы .a сохранялись в $GOPATH/pkg).
flowchart LR
    classDef process  fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
    classDef success  fill:#064e3b,stroke:#34d399,stroke-width:1px,color:#f8fafc
    classDef error    fill:#7f1d1d,stroke:#f87171,stroke-width:1px,color:#f8fafc
    classDef warning  fill:#78350f,stroke:#fbbf24,stroke-width:1px,color:#f8fafc
    classDef entry    fill:#1e3a5f,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
    classDef aux      fill:#334155,stroke:#64748b,stroke-width:1px,color:#f8fafc
    classDef system   fill:#312e81,stroke:#a78bfa,stroke-width:1px,color:#f8fafc
    classDef data     fill:#132d29,stroke:#2dd4bf,stroke-width:1px,color:#f8fafc
    classDef network  fill:#881337,stroke:#fb7185,stroke-width:1px,color:#f8fafc
    classDef accent   fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#f8fafc
    A["go install github.com/user/tool@latest"]:::entry --> B["Компиляция"]
    B --> C{"Тип пакета"}
    C -- Библиотека --> D["Кэш сборки GOCACHE"]
    C -- main пакет --> E["Бинарный файл"]
    E --> F["Перемещение в GOBIN"]
    F --> G["Глобальный доступ из CLI"]
  

Настройка окружения: $GOBIN

Ключевое условие для комфортной работы с go install — правильная настройка переменных окружения.

По умолчанию Go использует структуру GOPATH. Однако современной лучшей практикой является явное указание переменной GOBIN.

Bash
# ~/.bashrc или ~/.zshrc
export GOBIN=$HOME/go/bin
export PATH=$PATH:$GOBIN

Если GOBIN не установлен, бинарники падают в $GOPATH/bin. Если вы не добавите эту директорию в $PATH, команда go install отработает "успешно", но вы не сможете запустить установленную утилиту просто набрав её имя в командной строке.


Версионирование: Суффикс @version

До появления модулей (Go 1.16), go get использовался и для зависимостей, и для установки инструментов. Это приводило к хаосу: go get менял go.mod вашего проекта, когда вы просто хотели установить линтер.

Сейчас принят четкий стандарт:

  • go install pkg@version — для установки инструментов (CLI). НЕ меняет go.mod текущего проекта.
  • go get pkg — для управления зависимостями проекта (устаревает в пользу go get только для обновлений, но go mod tidy предпочтительнее).

Примеры установки популярных инструментов:

Bash
# Установка последней версии линтера
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

# Установка конкретной версии (важно для CI reproducibility)
go install mvdan.cc/gofumpt@v0.5.0

# Установка генератора моков
go install github.com/vektra/mockery/v2@v2.38.0

Замена бинарников и Конфликты

Если вы установили tool@v1.0, а затем запустили go install tool@v2.0, Go просто перезапишет бинарник в $GOBIN. Там не может быть двух версий одной утилиты одновременно. Имя файла бинарника определяется последним сегментом пути импорта (или значением go install -name, что используется редко).

Это создает классическую проблему "dependency hell" для инструментов CLI, но в Go она решается просто: вы устанавливаете ту версию, которая нужна вам прямо сейчас. Если вам нужно держать несколько версий одновременно, придется переименовывать бинарники вручную или использовать менеджеры версий.

Для командной разработки принято фиксировать инструменты через файл tools.go с тегом сборки //go:build tools, что позволяет зафиксировать точные версии генераторов кода в go.mod и вызывать go install воспроизводимо на любой машине и в CI.


go install vs go build -o

Характеристика go build -o /path/bin/app go install
Цель Гибкая сборка для распространения или тестирования. Стандартная установка инструментов в систему.
Зависимости Требует явного указания пути вывода. Знает "правильное место" ($GOBIN) автоматически.
Версионирование Нет встроенной поддержки @version при сборке локального кода. Позволяет скачивать и собирать конкретные версии удаленных репозиториев.
Использование CI/CD пайплайны, создание релизов. Локальная разработка, установка линтеров, генераторов.

Итог

  1. go install — это способ "зарегистрировать" программу в ОС, положив её в $GOBIN.
  2. Всегда добавляйте $GOBIN в системный $PATH.
  3. Используйте суффикс @version (например, @latest), чтобы установить инструмент, не затрагивая зависимости текущего проекта.
  4. В современном режиме модулей go install компилирует библиотеки в кэш GOCACHE, а устанавливает в $GOBIN только main-пакеты.

Теперь, когда у нас установлены необходимые инструменты, самое время научиться проверять работоспособность нашего кода. В следующей статье мы перейдем к одной из самых мощных частей тулчейна — встроенному фреймворку тестирования. Читаем: 6. go test. Запуск тестов и флаги.