Переменные среды и Go-модули
Редактор ты настроил ещё в первом уроке и с тех пор пишешь в нём весь курс. Теперь разберёмся, что у Go под капотом: где он ищет модули, куда складывает кеш и как объяснить ему, что репозиторий компании качать через прокси не надо.
Переменные среды Go
Все настройки Go хранятся в переменных среды. Посмотреть их можно одной командой:
go env
Ключевые переменные
# Где установлен Go
go env GOROOT
# /usr/local/go
# Где живут ваши модули и бинарники
go env GOPATH
# /Users/username/go
# Прокси для скачивания модулей
go env GOPROXY
# https://proxy.golang.org,direct
# Что скачивать напрямую, минуя прокси (приватные репозитории компании)
go env GOPRIVATE
# пусто по умолчанию
# Где лежит кэш скачанных модулей
go env GOMODCACHE
# /Users/username/go/pkg/mod
Настройка PATH
Чтобы запускать установленные Go-программы из любого места, добавьте $GOPATH/bin в PATH:
# ~/.bashrc или ~/.zshrc
export PATH=$PATH:$(go env GOPATH)/bin
Проверка:
# Установим полезную утилиту
go install golang.org/x/tools/cmd/goimports@latest
# Должна работать из любой директории
goimports --help
Изменение переменных
# Временно (для текущей сессии)
export GOPATH=/custom/path
# Постоянно через go env
go env -w GOPATH=/custom/path
go env -w GOPRIVATE=github.com/mycompany/*
Полезные Go-утилиты
Расширение редактора ставит gopls и базовые инструменты само. Отдельно
доставляют то, что нужно в терминале и в CI - там редактора нет:
# Форматирование + импорты (то же, что делает редактор при сохранении,
# но применимо ко всему проекту разом и в CI)
go install golang.org/x/tools/cmd/goimports@latest
# Линтер: находит то, что компилятор пропускает - непроверенные ошибки,
# затенённые переменные, мёртвый код
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Статический анализ, входит в поставку Go
go vet ./...
# Документация по стандартной библиотеке локально, без интернета
go install golang.org/x/tools/cmd/godoc@latest
godoc -http=:6060
Go Modules
Каждый проект начинается с инициализации модуля:
mkdir myproject && cd myproject
go mod init github.com/username/myproject
Файл go.mod - манифест проекта:
module github.com/username/myproject
// Директива go задаёт минимальную версию языка для модуля.
// Ставьте ту, на которой реально собираете: она включает соответствующие
// возможности языка и правила сборки.
go 1.24
require (
github.com/gin-gonic/gin v1.10.0
)
Основные команды:
go mod tidy # удалить неиспользуемые, добавить недостающие
go mod download # скачать зависимости
go mod vendor # скопировать зависимости в vendor/
Приватные модули компании
Эта настройка понадобится в первый же рабочий день, и без неё ничего
не соберётся. По умолчанию Go качает зависимости не напрямую из репозитория,
а через публичный прокси proxy.golang.org и сверяет контрольные суммы
с sum.golang.org. Для открытых библиотек это быстро и безопасно.
С приватным репозиторием компании выходит иначе: прокси до него не достучится
и вернёт 410 Gone или 404, а сообщение будет выглядеть так, будто модуля
не существует:
go: gitlab.company.ru/backend/auth@v1.2.0: verifying module:
gitlab.company.ru/backend/auth@v1.2.0: reading
https://sum.golang.org/lookup/...: 410 Gone
Решение - сказать Go, какие пути качать напрямую, минуя прокси и проверку сумм:
go env -w GOPRIVATE=gitlab.company.ru/*,github.com/mycompany/*
Одна переменная выключает для этих путей и прокси, и sum.golang.org сразу.
Дальше Go пойдёт в репозиторий обычным git clone, и упрётся в следующее:
по HTTPS он попросит логин и пароль. Обычно доступ настроен по SSH-ключу,
поэтому git просят подменять протокол:
git config --global url."git@gitlab.company.ru:".insteadOf "https://gitlab.company.ru/"
Когда сборка ведёт себя странно
Три команды, которые закрывают почти все загадочные случаи с зависимостями:
# Откуда вообще взялся этот пакет: покажет цепочку импортов до него
go mod why github.com/some/package
# Проверить, что скачанное совпадает с контрольными суммами в go.sum
go mod verify
# Снести кеш модулей целиком (~/go/pkg/mod) - последнее средство,
# когда кеш повреждён и ошибки нелогичны
go clean -modcache
go mod why полезнее, чем кажется. Когда go mod tidy тянет в проект
незнакомую библиотеку, вопрос не «что это», а «кто её попросил» - и ответ
почти всегда какая-то транзитивная зависимость.
Мини-задание
- Напечатай
os.Getenv("НЕТ_ТАКОЙ")и сравни сos.LookupEnv. Разница между «пусто» и «не задано» однажды будет стоить инцидента - Запусти программу с переменной прямо в команде:
PORT=9090 go run . - Посмотри дерево зависимостей:
go mod graph | head -20, и почему пришла конкретная библиотека:go mod why <модуль> - Выполни
go mod tidyи посмотри диффом, что изменилось вgo.modиgo.sum - Загляни в
go.sumи объясни, зачем там по две строки на модуль
Итоги
Теперь ты умеешь:
- ✅ Читать и менять настройки через
go envиgo env -w - ✅ Различать
GOROOT(сам Go) иGOPATH(кеш и бинарники) - ✅ Подключать приватные репозитории через
GOPRIVATEиinsteadOf - ✅ Разбираться, откуда взялась зависимость, и чинить кеш модулей
Мини-практика
Выполни go env GOPATH GOROOT GOMODCACHE и посмотри, где что лежит.
Затем в любом своём проекте запусти go mod why для одной из зависимостей
в go.mod и проследи цепочку импортов до неё.
Дальше - горутины и конкурентность.