Подробно о модулях Go

Go
Подробно о модулях Go

Оригинальная ссылка:Подробно о модулях Go

Go 1.11 и Go 1.12 содержат предварительныеGo ModulesДа, и Go 1.13, запланированный на август 2019 года, будет использовать модули Go по умолчанию во время всей разработки.

Go Modules предназначен для улучшения опыта использования кода других разработчиков, то есть для добавления зависимостей (модулей, пакетов), а также для обеспечения правильности и безопасности кода. А модули Go могут использовать переменную среды GOPROXY для решения проблемы, связанной с тем, что go get нельзя использовать в материковом Китае.

Поэтому необходимо узнать о модулях Go.

Golang Logo
Golang Logo

модель

Модули Go имеют три режима в Go 1.11 и Go 1.12, определяемые переменной среды GO111MODULE:

  • Режим по умолчанию (эта переменная среды не установлена ​​илиGO111MODULE=auto): Инструменты командной строки Go используют модули Go, когда выполняются оба следующих условия:
    • Текущий каталог не находится в GOPATH/src/;
    • Файл go.mod существует в текущем каталоге или в верхнем каталоге.
  • режим GOPATH (GO111MODULE=off): инструменты командной строки Go никогда не используют модули Go. Вместо этого он ищет зависимости в каталоге поставщика и GOPATH.
  • Перейти в режим модулей (GO111MODULE=on): Инструменты командной строки Go используют только модули Go и никогда не обращаются к GOPATH. GOPATH больше не является каталогом импорта, но он по-прежнему хранит загруженные зависимости (GOPATH/pkg/mod/) и установленные команды (GOPATH/bin/), удаляется только GOPATH/src/.

В Go 1.13 по умолчанию используется шаблон Go Modules, поэтому сказанное выше можно игнорировать, как только Go 1.13 будет выпущен и будет использоваться в производстве.

Основной файл: go.mod

Ниже приведен наиболее полный пример файла go.mod:

module my/thing
go 1.12
require other/thing v1.0.2 // 这是注释
require new/thing/v2 v2.3.4 // indirect
require(
  new/thing v2.3.4
  old/thing v0.0.0-20190603091049-60506f45cf65
)
exclude old/thing v1.2.3
replace bad/thing v1.4.5 => good/thing v1.4.5

Он всеобъемлющий и сложный. Но на самом деле файл go.mod не так сложен в реальных проектах, и когда файл существует, никаких дополнительных шагов не требуется: такие команды, как go build, go test и даже go list, автоматически добавят новые зависимости, необходимые для выполнения импорта.

А теперь давайте более подробно рассмотрим состав файла go.mod:

Файл go.mod ориентирован на строки, текущий модуль (основной модуль) обычно находится в первой строке, за ним следуют зависимости, упорядоченные по пути.

Каждая строка содержит директиву, состоящую из начального глагола, за которым следуют аргументы.

Все ведущие глаголы функционируют следующим образом:

  • module: укажите путь к модулю.
  • go: Установите ожидаемую языковую версию.
  • require: требуется определенный модуль данной версии или выше.
  • exclude: Исключает использование определенных версий модулей, запрещенные версии модулей считаются недоступными и не могут быть возвращены запросом.
  • replace: заменить исходную версию модуля другой версией модуля.

ведущие глаголы также могут бытькусок, создав блок со скобками (строки 5-8), как импорт в Go:

import (
    "errors"
    "fmt"
    "log"
)

Комментарии (строки 3-4) можно использовать в одну строку// 这是注释Комментарии, но не несколько строк/* 这是注释 */Примечания. иindirectКомментарий (строка 4) отмечает, что модуль не импортируется текущим модулем напрямую, а только косвенно.

Файл go.mod существует только в корневом каталоге модуля, путь импорта в подкаталоге будет использоватьпуть импорта модуля + путь подкаталогаформа. Например: если вы создаете подкаталог с именем world, вам не нужно использовать его в подкаталогеgo mod initкоманда, инструмент командной строки Go автоматически распознает ее как часть модуля hello, поэтому ее путь импорта — hello/world.

Инструменты командной строки Go автоматически обрабатывают версию модуля, указанную в go.mod. в исходном кодеimportЕсли указанный модуль не существует в файле go.mod, инструмент командной строки Go автоматически выполнит поиск модуля и добавит последнюю версию (последнюю помеченную и непредварительную стабильную версию) в файл go. файл мод.

Если тега нет, используется псевдоверсия (строка 7), которая представляет собой синтаксис версии, предназначенный для пометки нетегированных коммитов (некоторые пакеты на golang.org/x/ не имеют тегов). как:v0.0.0-20190603091049-60506f45cf65.

Первая часть — это семантический номер версии, который используется для обозначения версии; средняя часть — это время фиксации в формате UTC, которое используется для сравнения двух псевдоверсий для определения порядка; последняя часть — это префикс версии. хэш коммита, который используется для обозначения того, где находится версия коммита.

Файл управления версиями: go.sum

Пример выглядит следующим образом:

github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=

Каждая строка состоит из пути импорта модуля, конкретной версии модуля и ожидаемого хэша.

Каждый раз, когда модуль отсутствует, если он не существует в кеше, его необходимо загрузить и вычислить его хэш для добавления в go.sum; если он существует в кеше, он должен сопоставиться с существующей записью в go.sum.

Таким образом, пользователи, которые создают программное обеспечение, могут использовать хэш, чтобы убедиться, что их сборка такая же, как ваша сборка (go mod verify) и получить одну и ту же версию независимо от того, как они извлекают зависимости. В то же время это также гарантирует, что зависимости проекта не будут иметь неожиданных вредоносных модификаций и других проблем. Вот почему файл go.sum добавлен в систему управления версиями (Git).

Плюс опция Go ModulesВыбор минимальной версииСтратегия (по умолчанию используется самая старая разрешенная версия каждого модуля, задействованного в сборке, чтобы выпуск новой версии не влиял на сборку) позволяет воспроизводимые сборки (с получением тех же результатов при повторных сборках).

Семантическое управление версиями

чтоСемантическое управление версиями? Semantic Versioning — это набор соглашений, установленных основателем Gravatar и соучредителем GitHub Томом Престоном-Вернером. В соответствии с этим набором соглашений семантические номера версий и то, как они обновляются, содержат много полезной информации.

Семантический формат номера версии:X.Y.Z(основной номер версии. дополнительный номер версии. номер редакции), способ использования следующий:

  • Увеличивайте основной номер версии при внесении изменений, не совместимых с предыдущими версиями.
  • Дополнительный номер версии увеличивается, когда API остается обратно совместимым с новыми дополнениями и модификациями.
  • Увеличивайте номер версии, когда проблема исправлена, не затрагивая API.

Например, есть семантический номер версии:v0.1.2, основной номер версии — 0, дополнительный номер версии — 1 и номер редакции — 2. в то время как предыдущийv— это первая буква версии (версия), которая используется соглашением языка Go, а стандартная семантическая версия не имеет этого соглашения.

Таким образом, при использовании инструмента командной строки Go или файла go.mod вы можете использовать семантический номер версии длязапрос модуля, конкретные правила заключаются в следующем:

  • По умолчанию(@latest): будет соответствовать последней доступной версии с тегами или последней версии без тегов исходного репозитория.
  • полностью указанная версия (@v1.2.3): будет соответствовать указанной версии.
  • префикс версии (@v1или@v1.2): будет соответствовать последней доступной версии тега с этим префиксом.
  • сравнение версий (@<v1.2.3или@>=v1.5.6): будет соответствовать доступной версии тега, ближайшей к цели сравнения.<последняя версия меньше той версии,>Это самая старая версия больше, чем эта версия. При использовании Unix-подобной системы заключайте строку в кавычки, чтобы знаки больше или меньше не интерпретировались как перенаправление. как:go get 'github.com/gin-gonic/gin@<v1.2.3'.
  • Укажите фиксацию (@c856192): будет соответствовать версии на момент фиксации.
  • укажите ветку(@master): будет соответствовать версии ветки.

语义化导入版本
Семантическая версия импорта

Как показано на рисунке выше, чтобы упростить пользователям модулей Go переход со старой версии на новую, язык Go официально предлагает два важных правила:

  • Правило совместимости импорта: если старый пакет и новый пакет имеют один и тот же путь импорта, новый пакет должен быть обратно совместим со старым пакетом.
  • Правило управления версиями семантического импорта: каждая отдельная основная версия (т. е. несовместимый пакетv1илиv2) с использованием разных путей импорта, заканчивающихся основной версией, и максимум одной из каждой основной версии. например: аrsc.io/quote,Одинrsc.io/quote/v2,Одинrsc.io/quote/v3.

А интеграция с ветками Git выглядит следующим образом:

Go Modules 分支
Ветка Go Modules

каталог поставщиков

Ранее каталог поставщиков использовался для двух целей:

  • Точную версию зависимости можно использовать для сборки.
  • Эти зависимости гарантированно будут доступны, даже если исходная копия исчезнет.

И модули теперь имеют лучший механизм для обоих:

  • Указав точную версию зависимости в файле go.mod.
  • Доступность определяется кэширующим прокси ($GOPROXY)выполнить.

И каталогу vendor тоже сложно управлять этими зависимостями, и со временем он попадет в ту же дилемму, что и черная дыра node_modules.

node_modules 黑洞
node_modules черная дыра

Таким образом, по умолчанию использование Go Modules полностью игнорирует зависимости от поставщиков, но для плавного перехода вы можете использоватьgo mod vendorКоманда может создать каталог поставщиков.

и используйте его в инструментах командной строки Go-mod=vendorпараметры, такие как:go test -mod=vendor ./...; или установите для переменной среды GOFLAGS значение-mod=vendor, который предполагает, что каталог поставщика содержит правильные копии зависимостей, и строит игнорируя описания зависимостей в файле go.mod.

Переменная среды GOPROXY

Установка переменной среды GOPROXY может решить проблему, из-за которой go get нельзя использовать в материковом Китае:

Пучокexport GOPROXY=https://goproxy.ioПросто напишите в конфигурационный файл Shell.

Общие команды

  • go mod init: Создайте новый модуль, инициализируйте файл go.mod и параметром является путь импорта модуля.Эта форма рекомендуется. как:go mod init github.com/linehk/example.
  • go get: изменить версию зависимости (или добавить новую).
  • go build,go testИ т. д. Команды: инструменты командной строки Go добавляют новые зависимости по мере необходимости. как:go test ./..., чтобы протестировать текущий модуль.
  • go list -m all: Распечатать зависимости текущего модуля.
  • go mod tidy: Удалите бесполезные зависимости.
  • go list -m -versions github.com/gin-gonic/gin: Список всех версий этого модуля.
  • go mod verify: проверьте хэш.

Интеграция с GoLand

Для использования модулей Go в GoLand 2019.1.3 требуется две настройки:

  1. Настройки -> Go -> Go Modules (vgo), установите флажок Включить интеграцию Go Modules (vgo), чтобы включить Go Modules, и введите в поле ввода Proxy.https://goproxy.io. как показано на рисунке:
    在 GoLand 中使用 Go Modules 设置 1
    Использование модулей Go в программе GoLand Setup 1
  2. Настройки -> Перейти -> GOPATH, установите флажок Индексировать весь GOPATH, чтобы проиндексировать весь GOPATH, иначе пакет не может быть импортирован. как показано на рисунке:
    在 GoLand 中使用 Go Modules 设置 2
    Использование модулей Go в GoLand Setup 2

После выполнения вышеуказанных настроек вы можете нажать Синхронизировать пакеты..., чтобы загрузить пакет при импорте пакета, которого нет в кеше:

下载包
Скачать пакет

Ссылка на ссылку

Command go

Go & Versioning

Семантическое управление версиями 2.0.0