Модули Go: поиск нужной псевдо-версии (vX.Y.Z- ‹timestamp› - ‹commit›) требуемого пакета

Пробую модули Go. Мой проект требует libarary 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 for a 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.

Как мне выяснить эти строки версии? Я предполагаю, что в какой-то момент эти golang.org/x пакеты будут версироваться в соответствии с семантическим управлением версиями, но для того, чтобы действительно попробовать go mod, мне нужно выяснить эти go mod сейчас.


person Patrick Bucher    schedule 09.09.2018    source источник


Ответы (5)


Версия формы v0.0.0-20180906233101-161cd47e91fd означает, что в репозитории git нет версий с тегами. Таким образом, go mod генерирует один на основе последнего времени фиксации и префикса хэша фиксации.

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

go mod init yourmodulename

Или создайте пустой файл go.mod, содержащий только следующее:

module yourmodulename

затем запустите go mod tidy, это найдет все зависимости, добавит недостающие и удалит неиспользуемые зависимости.

person nijm    schedule 09.09.2018
comment
Незначительное примечание: вам не обязательно запускать go mod tidy, чтобы команда go автоматически определяла соответствующую псевдоверсию в этом случае. Другие команды, такие как go build, go test и т. Д., Также записали бы версию. Дополнительные сведения см. В этом ответе. go mod tidy имеет использует, но иногда люди думают, что им нужно запускать его чаще, чем это необходимо. В любом случае все еще в силе. - person typical182; 01.08.2019

Обновить

Эта команда - лучшее решение для добавления команды replace в go.mod, а не ручное использование git, которое я изначально опубликовал:

go mod edit -replace github.com/docker/docker=github.com/docker/engine@ea84732a7725

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

replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20191113042239-ea84732a7725+incompatible

В качестве альтернативы включите версию докера с тегами.

go mod edit -replace github.com/docker/[email protected]=github.com/docker/engine@ea84732a7725

для

replace github.com/docker/docker v1.13.1 => github.com/docker/engine v17.12.0-ce-rc1.0.20191113042239-ea84732a7725+incompatible

Спасибо @ Shivam010 на носителе


Исходный, устаревший ответ

Вот как я это сделал.

Оформить заказ в репозиторий по нужной ветке / тегу. например

git clone -b v19.03.5 [email protected]: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
person nicerobot    schedule 22.12.2019
comment
FWIW, довольно опасно пытаться отформатировать это самостоятельно, и вы можете сделать это тонко неправильно, что позже вас укусит. Намного лучше позволить команде 'go' сделать это за вас, как описано в stackoverflow.com/a/57315225/11210494 - person typical182; 14.02.2020
comment
Это очень полезно! Если вы хотите вставить переменные времени сборки с помощью Golang в двоичный, то это самый хороший способ понять это, как я нашел! - person SteveCoffman; 14.02.2020
comment
@ типичный182 Не могли бы вы протестировать github.com/docker/[email protected] с go get? Я серьезно хотел бы знать, как использовать go get для создания псевдо-версии для этого пакета. Рекомендую проверить, работает ли он. Просто запустить то, что вы ожидаете, go get github.com/docker/docker/[email protected], не работает с but does not contain package github.com/docker/docker/engine. Если бы какая-либо из go команд, которые я пробовал, работала до публикации, я бы не поделился ею, я бы абсолютно предпочел использовать go. Если у вас есть решение, использующее go get, поделитесь, пожалуйста! - person nicerobot; 29.02.2020
comment
Докер - сложный случай. Наверное, имеет смысл задать новый вопрос? Если вы прокомментируете здесь ссылку, я постараюсь ответить там. - person typical182; 01.03.2020

Автор использует строки версии, такие как v0.0.0-20170922011244-0744d001aa84, состоящие из индикации semver v0.0.0, отметки времени и чего-то вроде идентификатора фиксации git.

Как мне выяснить эти строки версии?

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

Ежедневный рабочий процесс

Типичный ежедневный рабочий процесс может быть следующим:

  • При необходимости добавьте операторы импорта в свой .go код.
  • Стандартные команды, такие как go build, go test или go mod tidy, будут автоматически добавлять новые зависимости по мере необходимости для выполнения импорта (обновление go.mod и загрузка новых зависимостей). По умолчанию будет использоваться @latest версия новой прямой зависимости.
  • When needed, more specific versions of dependencies can be chosen with commands such as:
    • go get [email protected]
    • 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, то вместо этого она будет записана как псевдо- version в вашем 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, что упрощает рассуждение о какая фиксация будет считаться «позже», чем другая фиксация, или фактический тег semver будет считаться «позже», чем отдельная фиксация.

Управление версиями зависимостей

Вы можете узнать больше обо всем вышеперечисленном в Раздел «Как обновить и понизить зависимости» вики-страницы модулей Go, который также содержит дополнительные ссылки на официальную документацию.

person typical182    schedule 01.08.2019
comment
Что, если эти псевдоверсии находятся в директивах replace, которые требуются в проекте, импортирующем зависимости Kubernetes (я думаю)? - person nckturner; 16.09.2020
comment
Обратите внимание, что начиная с Go1.16 команды сборки, такие как go build и go test, ведут себя как если -mod=readonly использовался и больше не будет автоматически обновлять go.mod (как указано во втором пункте ежедневного рабочего процесса). Вы можете использовать -mod=mod, чтобы разрешить команде изменять go.mod, как раньше. (При желании можно использовать переменную среды GOFLAGS для установки флагов по умолчанию для команд Go). - person Dave C; 25.06.2021

Теперь я немного прочел документацию (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.

person Patrick Bucher    schedule 09.09.2018

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

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

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

person megZo    schedule 24.06.2021
comment
Канонический способ добавить такую ​​строку require в go.mod - через go get, например go get golang.org/x/net@161cd47e91fd (или просто go get golang.org/net для @latest). - person Dave C; 25.06.2021