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

(Я позаимствовал фрагмент кода из ответа Патрика выше)

Другие вопросы по тегам