Go Modules: выяснение версии необходимого пакета
Я пробую модули Go. Мой проект требует библиотеки golang.org/x/net/html
так я определила это go.mod
файл:
module github.com/patrickbucher/prettyprint
require golang.org/x/net/html
И написал эту демонстрационную программу, чтобы проверить, загружается ли зависимость при компиляции:
package main
import (
"fmt"
"log"
"os"
"golang.org/x/net/html"
)
func main() {
doc, err := html.Parse(os.Stdin)
if err != nil {
log.Fatal(err)
}
fmt.Println(doc)
}
Когда я запускаю go build, я получаю это сообщение об ошибке:
go: errors parsing go.mod:
~/prettyprint/go.mod:3: usage: require module/path v1.2.3
Очевидно, я пропустил номер версии. Но какой взять? Я наткнулся на статью под названием Takig Go Modules для Spin, где я нашел пример go.mod
файл, содержащий ссылки на golang.org/x
пакеты:
module github.com/davecheney/httpstat
require (
github.com/fatih/color v1.5.0
github.com/mattn/go-colorable v0.0.9
github.com/mattn/go-isatty v0.0.3
golang.org/x/net v0.0.0-20170922011244-0744d001aa84
golang.org/x/sys v0.0.0-20170922123423-429f518978ab
golang.org/x/text v0.0.0-20170915090833-1cbadb444a80
)
Автор использует строки версии, такие как v0.0.0-20170922011244-0744d001aa84
, состоящий из индикации semver v0.0.0, отметки времени и чего-то похожего на git commit ID.
Как мне выяснить эти строки версии? Я думаю, те golang.org/x
пакеты будут версионированы в соответствии с семантическим версионированием в какой-то момент, но чтобы действительно попробовать go mod
Мне нужно выяснить это сейчас.
5 ответов
Теперь я читаю немного дальше в документации (go help modules
) и наткнулся на go mod tidy
:
Команда 'go mod tidy' создает это представление, а затем добавляет все отсутствующие требования к модулю и удаляет ненужные.
Поэтому, когда я откажусь от требования golang.org/x/net/html
и подрезать мой go.mod
файл к этому:
module github.com/patrickbucher/prettyprint
А потом беги go mod tidy
, тогда требование с номером версии правильно вычислено на основе пути импорта в моем исходном коде, и, таким образом, go.mod
став:
module github.com/patrickbucher/prettyprint
require golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
Теперь оба go list
а также go build
Работа.
Вот как я это делаю.
Оформить заказ в репозиторий по нужной ветке / тегу. например
git clone -b v19.03.5 git@github.com:docker/engine.git
потом
cd engine
TZ=UTC git --no-pager show \
--quiet \
--abbrev=12 \
--date='format-local:%Y%m%d%H%M%S' \
--format="%cd-%h"
И я получаю
20191113042239-ea84732a7725
Для использования в go.mod
как
replace github.com/docker/docker v1.13.1 => github.com/docker/engine v0.0.0-20191113042239-ea84732a7725
Версия формы v0.0.0-20180906233101-161cd47e91fd
означает, что в репозитории git нет помеченных версий. Так go mod
генерирует один на основе последнего времени коммита и префикса хэша коммита.
Чтобы получить правильный go.mod
Запустите файл, используя следующую команду (при условии, что go 1.11):
go mod init yourmodulename
Или создайте пустой файл go.mod, который просто содержит следующее:
module yourmodulename
затем беги go mod tidy
, он найдет все зависимости, добавит отсутствующие и удалит неиспользуемые зависимости.
Автор использует строки версии, такие как v0.0.0-20170922011244-0744d001aa84, состоящие из индикации semver v0.0.0, метки времени и чего-то вроде идентификатора фиксации git.
Как мне выяснить эти строки версии?
Вам никогда не придется вручную вычислять эти сложные строки версий, которые называются псевдоверсиями.
Ежедневный рабочий процесс
Типичный ежедневный рабочий процесс может быть следующим:
- Добавьте операторы импорта в свой
.go
код по мере необходимости. - Стандартные команды вроде
go build
,go test
, илиgo mod tidy
автоматически добавит новые зависимости по мере необходимости для выполнения импорта (обновлениеgo.mod
и скачивание новых зависимостей). По умолчанию@latest
будет использоваться версия новой прямой зависимости. - При необходимости можно выбрать более конкретные версии зависимостей с помощью таких команд, как:
go get foo@v1.2.3
go get foo@e3702bed2
go get foo@latest
go get foo@branch
- или путем редактирования
go.mod
прямо.
Обратите внимание, что вам не нужно было придумывать псевдоверсию самостоятельно в любом из этих примеров, даже при запросе конкретной фиксации (например, @e3702bed2
) или последней фиксации в ветке (например, @master
).
Когда у меня появляются псевдоверсии go.mod
?
Если вы получите версию, которая разрешается в допустимый тег semver с ведущимv
Такие как v1.2.3
или v1.2.4-beta-1
, то этот тег semver будет записан в вашем go.mod
файл. Если у версии нет допустимого тега semver, она будет записана как псевдоверсия в вашемgo.mod
файл, например v0.0.0-20171006230638-a6e239ea1c69
, который включает раздел версии, отметку времени фиксации и хеш фиксации.
В вашем конкретном случае golang.org/x/net/html
не имеет тегов semver, что означает, что если вы go get golang.org/x/net/html@latest
, или go get golang.org/x/net/html@0744d001aa84
, или просто сделай go build
после первого включения import "golang.org/x/net/html"
в вашем .go
файл, то golang.org/x/net/html будет записан в вашем go.mod
как псевдоверсию, но обратите внимание, что вам не нужно было самостоятельно вычислять сложную строку (потому что go
команда переводит запросы модулей, такие какgo get golang.org/x/net/html@0744d001aa84
в соответствующую псевдо-версию, когда это необходимо, и записывает результат в ваш go.mod
).
Почему был выбран формат псевдоверсии?
Формат псевдоверсии помогает обеспечить простой общий порядок для всех версий на основе стандартного упорядочивания семвера, что упрощает рассуждение о том, какая фиксация будет считаться "позже", чем другая фиксация, или будет ли фактический тег semver считаться "позже" чем отдельный коммит.
Управление версиями зависимостей
Вы можете узнать больше обо всем вышеперечисленном в разделе "Как обновить и понизить зависимости" вики-страницы модулей Go, которая также содержит дополнительные ссылки на официальную документацию.
Если вы хотите использовать конкретную фиксацию, которая еще не была помечена, вы можете сделать следующее:
module github.com/patrickbucher/prettyprint
require golang.org/x/net 73496e0df0ba4284f460d1955ddf6bb096957c9f
затем беги
go mod tidy
и вы автоматически увидите псевдоверсию в файле go.mod, став
module github.com/patrickbucher/prettyprint
require golang.org/x/net v0.0.0-20180906233101-161cd47e91fd
(Я позаимствовал фрагмент кода из ответа Патрика выше)