Инструмент управления пакетами Go (3): Go Modules

задняя часть Go

В предыдущей статье мы впервые представилиНесколько методов управления сумками, а затем специально представляет инструмент управления пакетами:glide. С выпуском Go 1.11, официального инструмента управления пакетамиGo Modulesстал популярным. В недавно выпущенной версии Go 1.12 расширена поддержкаGo Modulesслужба поддержки. В этой статье будет рассказано, как установить и использовать его в проекте.Go Modules.

Поддержка установки и активации Модулей

предварительное условие

Как упоминалось в начале этой статьи, это поддерживается только начиная с Go 1.11.Go Modules. Итак, версия Go по умолчанию >= 1.11.

$ go version
go version go1.12 darwin/amd64

Установил последнюю версию 1.12.

Активируйте, чтобы использовать

После установки мы можем активировать поддержку модуля одним из двух способов:

  • существует$GOPATH/srcвызовите команду go из каталога, отличного от текущего каталога или любого из его родительских каталогов с допустимымgo.modфайл и переменные окруженияGO111MODULEНе задано (или явно задано значение auto).
  • установить в наборе переменных окруженияGO111MODULE = onПосле этого вызовите команду go.

Как определить модули

Создайте один для текущего проектаgo.modдокумент.

когда проекта нетGOPATH, непосредственно выполнить:

go mod init

В противном случае произойдет следующая ошибка:

go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'

Поэтому нам нужно активировать Модули вручную:

$ export GO111MODULE=on 

затем выполнитьgo mod init. Это преобразует любой существующий файл dep Gopkg.lock или любую из других девяти поддерживаемых зависимостей, добавивrequireзаявление, чтобы соответствовать существующей конфигурации.

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

$ go mod init modtest

строительные блоки

При выполнении из корневого каталога модуля./...Шаблон соответствует всем пакетам в текущем модуле.go buildОтсутствующие или непереведенные зависимости будут автоматически добавлены по мере необходимости, чтобы выполнить импорт для этого конкретного вызова сборки:

$ go build ./...

тестовый модуль

$ go test ./...

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

$ go test all

настоящий бой

Создать проект

Создайте проект и перейдите в корневой каталог:

$ mkdir src/hello
$ cd src/hello

инициализация

$ go mod init github.com/keets2012/hello
go: creating new go.mod: module github.com/keets2012/hello

перейдите к инициализации мода и назовите пакет какgithub.com/keets2012/hello. Как видите, создано вместеgo.modдокумент.

реализовать простой метод

$ cat <<EOF > hello.go
package main

import (
    "fmt"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}
EOF

мы создалиhello.goфайл и вывести результат вызванного метода.

выполнение сборки

$ go build   # 构建可执行文件
$ ./hello  # 执行

Hello, world.  # 输出结果

После выполнения сборки мы получаем исполняемый файл, и выполняем его для получения результата.go.modФайл был обновлен, чтобы включить явные версии зависимостей, гдеv1.5.2даsemverотметка:

$ cat go.mod

module github.com/keets2012/hello

require rsc.io/quote v1.5.2

Обновление и понижение зависимостей

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

Так же какgo build,go testили дажеgo listТакая команда автоматически добавит новые зависимости, необходимые для выполнения импорта.

Чтобы просмотреть доступные второстепенные обновления и обновления программы исправлений для всех прямых и косвенных зависимостей:

go list -u -m all

Чтобы обновить до последней версии все прямые и косвенные зависимости текущего модуля:

  • бегатьgo get -uИспользуйте последнюю вторичную версию или версию исправления
  • go -u = patchИспользуйте последнюю версию патча

Чтобы обновить или перейти на более конкретную версию,go getРазрешено добавлением в параметр пакета@versionсуффикс или «запрос модуля», чтобы переопределить выбор версии, например.go get foo@v1.6.2,go get foo @ e3702bed2,илиgo foo @'<v1.6.2'.

semver

В предыдущем подразделе мы упоминалиsemver. Наилучшая практика, официально рекомендованная golang, называется semver, что является аббревиатурой.Semantic Versioning, что является семантической версией.

Семантическое определение

С точки зрения непрофессионала, это четкий и удобочитаемый формат версии, который четко отражает информацию о версии. Более подробные спецификации можно найти здесь.

Как говорится в спецификации, это выглядит такvX.Y.ZФорма явно более интуитивно понятна, чем строка хэшей, поэтому разработчики golang сосредоточатся на этом.

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

Роль упрощенной спецификации версии semver очевидна, но сама по себе эта причина, очевидно, немного неубедительна.Строгие ограничения на версию через semver могут максимизировать обратную совместимость и избежать «критических изменений», а это преследует golang. Эти двое поладили, так чтоgo modulesПредоставляется семантическая поддержка версий.

Если вы используете и распространяете пакеты без тегов версии или в версии 1.x, то вы, вероятно, не заметите никакой разницы, т.к.go modПоддерживаемые форматы следуют несколько раз от начала до конца, основное отличие заключается в пакетах версии 2.0.0 и более поздних.

«Если старый пакет и новый пакет имеют один и тот же путь импорта, новый пакет должен быть обратно совместим со старым пакетом» — go modules wiki

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

Ответ очень прост, мы можем добавить информацию о версии в конец пути импорта пакета, например:

module my-module/v2

require (
  some/pkg/v2 v2.0.0
  some/pkg/v2/mod1 v2.0.0
  my/pkg/v3 v3.0.1
)

Формат резюмируется какpkgpath/vN, где N — основной номер версии больше 1. Эта информация о версии также должна быть прикреплена при импорте в код, напримерimport "some/pkg/v2". Таким образом, путь импорта пакета изменился, и не нужно беспокоиться об ограничении обратной совместимости объектов с одинаковым именем, потому что golang считает, что разные пути импорта означают разные пакеты. Бывают, конечно, непредвиденные ситуации:

  • Эквивалентное требование gopkg.in/some/pkg.v2 v2.0.0 можно использовать при использовании формата gopkg.in.
  • добавить информацию о версии+incompatibleВозможно, вам не нужно указывать/vN,Например:require some/pkg v2.0.0+incompatible

В других случаях, если вы используете его напрямуюv2+версия приведет кgo modсообщить об ошибке.

Версия пакета v2+ может сосуществовать с другими пакетами других основных версий (при условии, что добавленный/vN), они будут рассматриваться как отдельные пакеты.

Кроме того/vNЭто не повлияет на ваш склад, вам не нужно создавать соответствующий склад v2, это простоgo modulesПросто добавлена ​​дополнительная информация.

Конечно, если вы не хотите следовать этой спецификации или нуждаетесь в совместимости с существующим кодом, укажите+incompatibleбудет разумным выбором. ноgo modulesТакое поведение не рекомендуется.

Используйте каталог поставщиков

Если тебе не нравитсяgo modДля кэширования можно использоватьgo mod vendorВернитесь в каталог поставщика, используемый godep или govendor для управления пакетами.

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

использоватьgo build -mod=vendorпостроить проект, потому что вgo modulesв режимеgo buildОн блокирует механизм вендора, поэтому для перезапуска механизма вендора требуются определенные параметры:

go build -mod=vendor
./hello
hello world!

Построить удалось. При публикации нужно только привести директорию вендора как с godep.

Суммировать

Эта статья в основном знакомитgo modulesНекоторые особенности и использование ,go modulesЭто официальный инструмент управления пакетами.Язык Go представляет еще один рабочий режим инструмента Go, вводя концепцию модуля.module-aware mode. В новом режиме работы модуль поддерживает управление версиями зависимостей пакетов.

Новый режим работы также приносит некоторые проблемы, в материковой части мы не можем пройти напрямуюgo getКоманда получает некоторые сторонние пакеты, наиболее распространенными из которых являютсяgolang.org/xРазличные отличные пакеты ниже. После работы под модулем,go buildбольше не будут заботиться о пакетах под GOPATH или поставщиком, ноGOPATH/pkg/modПроверьте есть ли кеш, если нет, то загрузит определенную версию модуля, а для некоторых пакетов модуля часто глючит на материке. В следующей статье мы представим реализацию конфигурации прокси модуля go.

Рекомендуемое чтение

Инструмент управления пакетами для Go

Подписывайтесь на свежие статьи, приглашаю обратить внимание на мой публичный номер

微信公众号

Ссылаться на

  1. Modules docs
  2. Пересмотрите модули go: использование и подробности