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.modfile.

Если есть проблема с сетью или одна из зависимостей удалена в удаленной системе контроля версий, это приведет к сбою сборки.

Чтобы обеспечить детерминированную сборку, 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 можно рассказать гораздо больше.

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

Я надеюсь, что вы найдете это полезным, и я увижу вас на следующем!