среда, 28 апреля 2021 г.

Обзор файла go.mod

Каждый модуль Go определяется файлом go.mod, который описывает свойства модуля, включая его зависимости от других модулей и от версий Go.

Эти свойства включают:

  • Путь к текущему модулю. Это должно быть место, из которого модуль может быть загружен инструментами Go, например расположение репозитория кода модуля. Он служит уникальным идентификатором в сочетании с номером версии модуля. Это также префикс пути к пакету для всех пакетов в модуле.
  • Минимальная версия Go, необходимая для текущего модуля.
  • Список минимальных версий других модулей, необходимых для текущего модуля.
  • Инструкции, необязательно, для замены необходимого модуля другой версией модуля или локальным каталогом, или для исключения определенной версии необходимого модуля.

Go создает файл go.mod, когда вы запускаете команду go mod init. В следующем примере создается файл go.mod, устанавливая путь к модулю модуля на example.com/mymodule:

$ go mod init example.com/mymodule

Используйте команды go для управления зависимостями. Команды гарантируют, что требования, описанные в вашем файле go.mod, остаются согласованными, а содержимое вашего файла go.mod является действительным. Эти команды включают команды go get and go mod tidy и go mod edit.

Вы можете получить справку из командной строки, набрав go help имя-команды, как в случае с go help mod tidy.

Пример

Файл go.mod включает директивы, показанные в следующем примере. Они описаны в этом посте.

module example.com/mymodule

go 1.14

require (
    example.com/othermodule v1.2.3
    example.com/thismodule v1.2.3
    example.com/thatmodule v1.2.3
)

replace example.com/thatmodule => ../thatmodule
exclude example.com/thismodule v1.3.0

module

Объявляет путь к модулю модуля, который является уникальным идентификатором модуля (в сочетании с номером версии модуля). Он становится префиксом импорта для всех пакетов, содержащихся в модуле.

Синтаксис

module module-path

module-path

Путь к модулю модуля, обычно это расположение репозитория, из которого модуль может быть загружен инструментами Go. Для версий модуля v2 и более поздних это значение должно заканчиваться основным номером версии, например /v2.

Примеры

В следующих примерах example.com заменяется доменом репозитория, из которого можно загрузить модуль.

  • Объявление модуля для модуля v0 или v1:

    module example.com/mymodule
    

  • Путь к модулю для модуля v2:

    module example.com/mymodule/v2
    

Заметки

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

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

Если сначала вы не знаете возможное местоположение репозитория модуля, рассмотрите возможность временного использования безопасной замены, такой как имя вашего домена или example.com, а также путь, следующий из имени модуля или исходного каталога.

Например, если вы разрабатываете в каталоге stringtools, ваш временный путь к модулю может быть example.com/stringtools, как в следующем примере:

go mod init example.com/stringtools

go

Указывает, что модуль был написан с учетом семантики версии Go, указанной в директиве.

Синтаксис

go minimum-go-version

minimum-go-version

Минимальная версия Go, необходимая для компиляции пакетов в этом модуле.

Примеры

Модуль должен работать на Go версии 1.14 или новее:

go 1.14

Заметки

Директива go изначально предназначалась для поддержки обратно несовместимых изменений языка Go. С момента появления модулей несовместимых языковых изменений не было, но директива go по-прежнему влияет на использование новых языковых функций:

  • Для пакетов в модуле компилятор отклоняет использование языковых функций, представленных после версии, указанной в директиве go. Например, если у модуля есть директива go 1.12, его пакеты могут не использовать числовые литералы, такие как 1_000_000, которые были введены в Go 1.13.
  • Если более старая версия Go собирает один из пакетов модуля и обнаруживает ошибку компиляции, в сообщении об ошибке указывается, что модуль был написан для более новой версии Go. Например, предположим, что у модуля есть версия 1.13, а в пакете используется числовой литерал 1_000_000. Если этот пакет собран с Go 1.12, компилятор отмечает, что код написан для Go 1.13.

Кроме того, команда go изменяет свое поведение в зависимости от версии, указанной в директиве go. Это имеет следующие эффекты:

  • В версии 1.14 или выше может быть включен автоматический вендоринг. Если файл vendor/modules.txt присутствует и согласуется с go.mod, нет необходимости явно использовать флаг -mod=vendor.
  • В версии 1.16 и выше шаблон пакетов all соответствует только пакетам, транзитивно импортированным пакетами и тестами в основном модуле. Это тот же набор пакетов, который оставлен go mod vendor с момента появления модулей. В более низких версиях all также включает пакеты тестов, импортированных пакетами в основном модуле, тесты этих пакетов и т. д.

Файл go.mod может содержать не более одной директивы go. Большинство команд добавят директиву go с текущей версией Go, если она отсутствует.

require

Объявляет модуль как зависимость, требуемую текущим модулем, указывая минимальную требуемую версию модуля.

Синтаксис

require module-path module-version

module-path

Путь к модулю модуля, обычно представляет собой объединение домена репозитория исходного кода модуля и имени модуля. Для версий модуля v2 и более поздних это значение должно заканчиваться основным номером версии, например /v2.

module-version

Версия модуля. Это может быть либо номер версии релиза, например v1.2.3, либо номер псевдо-версии, сгенерированный Go, например v0.0.0-20200921210052-fa0125251cc4.

Примеры

Требование релизной версии v1.2.3:

require example.com/othermodule v1.2.3

Требование версии, еще не имеющей тега в своем репозитории, с использованием номера псевдоверсии, сгенерированного инструментами Go:

require example.com/othermodule v0.0.0-20200921210052-fa0125251cc4

Заметки

Когда вы запускаете команду go, такую как go get, Go вставляет требуемые директивы для каждого модуля, содержащего импортированные пакеты. Когда модуль еще не имеет тега в своем репозитории, Go присваивает номер псевдоверсии, который он генерирует при запуске команды.

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

Дополнительные сведения о номерах версий в посте нумерация версий модулей.

Дополнительные сведения об управлении зависимостями.

replace

Заменяет содержимое модуля определенной версии (или всех версий) другой версией модуля или локальным каталогом. Инструменты Go будут использовать путь замены при разрешении зависимости.

Синтаксис

replace module-path [module-version] => replacement-path [replacement-version]

module-path

Путь к заменяемому модулю.

module-version

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

replacement-path

Путь, по которому Go должен искать нужный модуль. Это может быть путь к модулю или путь к каталогу в файловой системе, локальному для заменяющего модуля. Если это путь к модулю, вы должны указать значение версии для замены. Если это локальный путь, вы не можете использовать значение версии для замены.

replacement-version

Версия заменяемого модуля. Версия для замены может быть указана только в том случае, если replace-path является путем к модулю (а не локальным каталогом).

Примеры

Замена форком репозитория модуля

В следующем примере любая версия example.com/othermodule заменяется указанным форком ее кода.

require example.com/othermodule v1.2.3

replace example.com/othermodule => example.com/myfork/othermodule v1.2.3-fixed

Когда вы заменяете один путь модуля другим, не меняйте операторы импорта для пакетов в модуле, который вы заменяете.

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

Замена на другой номер версии

В следующем примере указывается, что версия v1.2.3 должна использоваться вместо любой другой версии модуля.

require example.com/othermodule v1.2.2

replace example.com/othermodule => example.com/othermodule v1.2.3

В следующем примере версия модуля v1.2.5 заменяется версией v1.2.3 того же модуля.

replace example.com/othermodule v1.2.5 => example.com/othermodule v1.2.3

Замена местным кодом

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

require example.com/othermodule v1.2.3

replace example.com/othermodule => ../othermodule

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

require example.com/othermodule v1.2.5

replace example.com/othermodule v1.2.5 => ../othermodule

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

Заметки

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

Используйте директивы exclude и replace для управления разрешением зависимостей во время сборки при сборке текущего модуля. Эти директивы игнорируются в модулях, зависящих от текущего модуля.

Директива replace может быть полезна в следующих ситуациях:

  • Вы разрабатываете новый модуль, кода которого еще нет в репозитории. Вы хотите протестировать с клиентами, использующими локальную версию.
  • Вы определили проблему с зависимостью, клонировали репозиторий зависимости и тестируете исправление с помощью локального репозитория.

Дополнительные сведения о замене необходимого модуля, в том числе с использованием инструментов Go для внесения изменений, в посте управление зависимостями.

Дополнительные сведения о номерах версий в посте нумерация версий модулей.

exclude

Задает модуль или версию модуля, которую необходимо исключить из графа зависимостей текущего модуля.

Синтаксис

exclude module-path module-version

module-path

Путь к модулю исключаемого модуля.

module-version

Конкретная версия, которую нужно исключить.

Пример

Исключить example.com/theirmodule версии v1.3.0

exclude example.com/theirmodule v1.3.0

Заметки

Используйте директиву exclude, чтобы исключить конкретную версию модуля, которая требуется косвенно, но по какой-то причине не может быть загружена. Например, вы можете использовать ее для исключения версии модуля с недопустимой контрольной суммой.

Используйте директивы exclude и replace для управления разрешением зависимостей во время сборки при сборке текущего модуля (основного модуля, который вы создаете). Эти директивы игнорируются в модулях, зависящих от текущего модуля.

Вы можете использовать команду go mod edit, чтобы исключить модуль, как в следующем примере.

go mod edit -exclude=example.com/theirmodule@v1.3.0

Дополнительные сведения о номерах версий в посте нумерация версий модулей.


Читайте также:


Комментариев нет:

Отправить комментарий