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. Она компилирует пакеты (используя тот же кэш и компилятор). Однако у неё есть два критических отличия:
- Назначение: Она сохраняет скомпилированный бинарник в специальную директорию
$GOBIN(или$GOPATH/bin, еслиGOBINне задан), а не в текущую рабочую директорию. - Сборка библиотек: Для пакетов библиотек (не
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.
# ~/.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предпочтительнее).
Примеры установки популярных инструментов:
# Установка последней версии линтера
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 пайплайны, создание релизов. | Локальная разработка, установка линтеров, генераторов. |
Итог
go install— это способ "зарегистрировать" программу в ОС, положив её в$GOBIN.- Всегда добавляйте
$GOBINв системный$PATH. - Используйте суффикс
@version(например,@latest), чтобы установить инструмент, не затрагивая зависимости текущего проекта. - В современном режиме модулей
go installкомпилирует библиотеки в кэшGOCACHE, а устанавливает в$GOBINтолькоmain-пакеты.
Теперь, когда у нас установлены необходимые инструменты, самое время научиться проверять работоспособность нашего кода. В следующей статье мы перейдем к одной из самых мощных частей тулчейна — встроенному фреймворку тестирования. Читаем: 6. go test. Запуск тестов и флаги.