GOPATH, GOPRIVATE и другие
Если вы разработчик в Go, скорее всего, вы уже сталкивались с этими загадочными терминами — GOPATH
, GOPRIVATE
, Go111module
и т. д.
В большинстве случаев вам не нужно заботиться о том, что они из себя представляют. Но иногда вы можете столкнуться с ошибками, которые резко затормозят вашу разработку.
В этой статье я избавлю вас от боли и покажу вам основы, которые вам нужны.
Давайте начнем!
Примечание. Следующие сведения относятся только к Go 1.15 и более поздним версиям.
ГОРУТ
GOROOT — это место, где хранится ваш Go SDK.
В нем хранятся компиляторы Go по умолчанию, исполняемые команды Go и библиотеки Go.
Вам не нужно изменять эту переменную, если вы не планируете использовать другую версию Go.
При импорте библиотеки Go сначала ищет файл в GOROOT
. Если файл не существует, он возвращается к GOPATH
.
ГОПУТ
GOPATH
содержит три каталога: pkg
, src
и bin
.
$GOPATH/упаковка
$GOPATH/pkg/mod
— это расположение по умолчанию дляGOMODCACHE
.- Следовательно,
$GOPATH/pkg/mod
хранит и кэширует зависимости, загруженные черезgo get
илиgo install
.
$GOPATH/бин
- В каталоге bin хранятся исполняемые команды, установленные через
go install
. - Эти команды включают сторонние команды и команды ваших исходных файлов.
- Команды Go по умолчанию, такие как
gofmt
, вместо этого хранятся в каталогеGOROOT/bin
.
$GOPATH/источник
- В каталоге src хранятся исходные файлы Go до появления модулей Go.
- Это стало менее значимым с появлением модулей Go.
Перейти Модули
До появления модулей Go проекты и зависимости Go должны были храниться в каталоге $GOPATH/src/
.
Не было управления версиями. Проекты в каталоге src с общими библиотеками в одной и той же стабильной версии, основной ветке.
После введения Go Modules изменилось следующее:
- Разработчикам разрешено создавать проекты за пределами
$GOPATH/src/
dir. - Каждый проект, также известный как модуль, представляет собой набор файлов и пакетов, предназначенных для совместного выпуска.
- Каждый модуль содержит файл
go.mod
, который определяет необходимые зависимости и версии. - Зависимости загружаются из соответствующих репозиториев во время сборки.
Go.mod
Файл go.mod
находится в каждом модуле go.
Файл go.mod
делает следующее:
- Определяет путь модуля — путь, используемый при импорте пакетов/файлов в том же модуле go.
- Определяет зависимости и версии, необходимые для успешной сборки модуля.
Go.sum
Когда удаленный сервер создает модуль, он извлекает и загружает зависимости, указанные в файле go.mod
, из соответствующих систем контроля версий.
Это неизбежно приводит к нескольким проблемам:
- Что произойдет, если кто-то злонамеренно изменит указанную версию библиотеки?
- Как мы можем гарантировать, что удаленный сервер извлечет библиотеку, содержащую точно такой же контент, как и нашу локальную копию?
Вот где go.sum
вступает в игру.
- Это контрольная сумма всех прямых и косвенных зависимостей, перечисленных в файле
go.mod
. - Он проверяет и гарантирует, что локальная загруженная копия зависимостей аналогична удаленной копии.
Приведи мод в порядок
go.mod tidy
обеспечивает обновление go.mod
.
Когда вы запускаете go mod tidy
, он делает следующее:
- Загружает необходимые зависимости и обновляет
go.mod
. - Удаляет ненужные зависимости от
go.mod
. (Примечание: он не удаляет библиотеки из локального кеша, он же$GOPATH/pkg/mod
)
Иди чисти -modcache
Когда вы выполняете go get
или go mod tidy
, Go загружает зависимости и кэширует их в GOMODCACHE
, который по умолчанию равен $GOPATH/pkg/mod/
.
Иногда вам может понадобиться удалить все загруженные пакеты, и именно это делает go clean -modcache
.
Он удаляет все загруженные пакеты в каталоге GOMODCACHE
.
Продавец модов
При сборке модуля на удаленном сервере сервер извлекает и загружает зависимости, указанные в файле go.mod
file.
Если есть проблема с сетью или одна из зависимостей удалена в удаленной системе контроля версий, это приведет к сбою сборки.
Чтобы обеспечить детерминированную сборку, go mod vendor
создает папку в вашем модуле Go и сохраняет исходные файлы ваших зависимостей в каталоге.
Каталог поставщика будет зафиксирован вместе с вашим изменением кода.
Это позволяет
- Детерминированное и последовательное построение.
- Изменения в зависимостях можно легко увидеть и просмотреть.
Однако это занимает дополнительное место и увеличивает время, затрачиваемое на клонирование репозитория, что приводит к увеличению продолжительности CI/CD.
ГОПРОКСИ
До появления GOPROXY
зависимости скачивались напрямую с удаленных VCS.
Это привело к двум фундаментальным проблемам — безопасности и доступности.
- Зависимости в удаленной системе контроля версий могут быть удалены в любое время.
- Зависимости в удаленной системе контроля версий могут быть изменены и скомпрометированы.
GOPROXY
— это централизованный репозиторий, в котором размещаются и кэшируются сторонние общедоступные модули.
Вместо того, чтобы получать данные с удаленных систем контроля версий, Go перенаправляет каждый запрос на загрузку в общедоступный GOPROXY
и проверяет загруженный модуль по общедоступной базе данных контрольных сумм Go.
GOPROXY
по умолчанию
GOPROXY="https://proxy.golang.org,direct"
Добавление direct
в GOPROXY
позволяет Go вернуться к VCS, если запрошенный модуль не найден в GOPROXY
.
ДАВАЙ В ПРИВАТ
GOPROXY
хорошо работает с публичными модулями. Однако это оставляет нас с другой проблемой.
Что произойдет, если запрошенная зависимость находится в частном репозитории, например репозитории вашей компании?
И тут на помощь приходит GOPRIVATE
. Он контролирует, какие модули команда Go считает частными, например
GOPRIVATE=*github.com/org_name
Go рассматривает любой путь, соответствующий этому шаблону, как частный и, следовательно, не будет использовать прокси-сервер и глобальную базу данных контрольных сумм.
Go111модуль
GO111module
обозначает режим с поддержкой модуля.
Когда Go был впервые выпущен, не было менеджера пакетов, пока модуль Go не был представлен в Go1.11.
В течение этого времени исходные файлы хранились в $GOPATH/src
, а go get
извлекал зависимости и сохранял их в $GOPATH/src
.
Короче говоря, то, как мы храним, загружаем и импортируем зависимости, отличается в эпоху до и после модуля Go.
GO111module=on
заставляет Go вести себя в соответствии с модулями Go, а GO111module=off
заставляет Go вести себя в соответствии с GOPATH.
Поскольку модули Go теперь являются практикой де-факто, GO111module=on
является поведением по умолчанию.
Закрытие
В деталях о командах Go и переменных env можно рассказать гораздо больше.
Вы будете сталкиваться с упомянутыми почти каждый день в процессе разработки.
Я надеюсь, что вы найдете это полезным, и я увижу вас на следующем!