21

我正在尝试 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 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 提交 ID 的东西组成。

我如何找出那些版本字符串?我猜这些golang.org/x包将在某个时候根据语义版本控制进行版本控制,但要真正尝试,我现在go mod需要弄清楚那些。

4

5 回答 5

32

更新

此命令是添加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

或者,包括一个标记的 docker 版本。

go mod edit -replace github.com/docker/docker@v1.13.1=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

感谢Medium 上的 @Shivam010


原始的,已弃用的答案

这就是我的做法。

签出所需分支/标签上的存储库。例如

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
于 2019-12-22T00:10:32.260 回答
13

表单的版本v0.0.0-20180906233101-161cd47e91fd意味着 git 存储库中没有标记的版本。所以go mod根据最新的提交时间和提交哈希的前缀生成一个。

要获得正确的go.mod文件,请使用以下命令开始(假设 go 1.11):

go mod init yourmodulename

或者创建一个只包含以下内容的空 go.mod 文件:

module yourmodulename

然后运行go mod tidy,这将找到所有依赖项,添加缺少的并删除未使用的依赖项。

于 2018-09-09T10:23:27.520 回答
10

作者正在使用像 v0.0.0-20170922011244-0744d001aa84 这样的版本字符串,由 semver 指示 v0.0.0、时间戳和看起来像 git 提交 ID 的东西组成。

我如何找出那些版本字符串?

您永远不需要手动找出那些称为伪版本的复杂版本字符串。

日常工作流程

您典型的日常工作流程可以是:

  • 根据需要将导入语句添加到您的.go代码中。
  • 标准命令,如go build,go testgo 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.3or 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, or go get golang.org/x/net/html@0744d001aa84, 或只是 do ,那么 golang.org/x/net/html 将作为伪版本记录在您的,但请注意,您不需要自己弄清楚复杂的字符串(因为该命令会在需要时将模块查询等转换为相应的伪版本,并将结果记录在您的 中)。go buildimport "golang.org/x/net/html".gogo.modgogo get golang.org/x/net/html@0744d001aa84go.mod

为什么选择伪版格式?

伪版本格式有助于基于标准semver排序在所有版本中提供简单的总排序,这使得更容易推断哪些提交将被视为比另一个提交“更晚”,或者实际的 semver 标签是否被视为“更晚”而不是单独的提交。

控制依赖版本

您可以在 Go Modules wiki 的“如何升级和降级依赖项”部分中阅读有关上述所有内容的更多信息,该部分还包含指向官方文档的其他链接。

于 2019-08-01T18:42:47.533 回答
4

现在我在文档(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

于 2018-09-09T07:21:29.867 回答
0

如果您想使用尚未标记的特定提交,您可以执行以下操作 -

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

(我从上面 Patrick 的回复中借用了代码片段)

于 2021-06-24T00:53:24.233 回答