乐趣区

关于go:记一次-go-mod-vendor-报错排查经过

一. 问题症状

咱们应用 jenkins 脚本执行 go build,用来构建线上服务器应用的二进制文件。构建过程中有这样一个步骤:

go mod vendor

该步骤将以 go.mod 文件中写明的包和版本为准下载第三方依赖并保留到本地的 vendor 目录。下载过程中将校验 go.sum 中的 hash 值是否同文件 hash 统一。

在理论执行中,遇到这样的谬误:

internal error: failed to find embedded files of github.com/marten-seemann/qtls-go1-18: //go:build comment without // +build comment

二. 排查通过

  1. 通过 qtls-go1-18 的仓库名能够察看到问题可能跟 go 1.18 的版本无关。
  2. 关上依赖的 github 仓库可见简介:
    Go standard library TLS 1.3 implementation, modified for QUIC. For Go 1.18.
    而咱们构建的环境 go env 输入的版本为 1.16

PS: go env

  1. 在 go 1.18 的 release notes 中查找相干信息:

//go:build lines
Go 1.17 introduced //go:build lines as a more readable way to write build constraints, instead of // +build lines. As of Go 1.17, gofmt adds //go:build lines to match existing +build lines and keeps them in sync, while go vet diagnoses when they are out of sync.

Since the release of Go 1.18 marks the end of support for Go 1.16, all supported versions of Go now understand //go:build lines. In Go 1.18, go fix now removes the now-obsolete // +build lines in modules declaring go 1.18 or later in their go.mod files.

For more information, see https://go.dev/design/draft-g…

报错的意思是 //go:build(1.18 版本反对)必须同 // +build 一起呈现。至此确认问题起因。
解决办法

业务代码并没有间接用到 qtls 包,且并没有间接依赖 qtls-go1-18 对应的 go 版本。此库为非间接依赖引入的,须要找出是那个包引入了这个依赖。

go mod why github.com/marten-seemann/qtls-go1-18

能够查看是谁引入该依赖。从输入能够看到:

# github.com/marten-seemann/qtls-go1-18
git.mycompany.com/group/projecta
git.mycompany.com/group/projectb
github.com/smallnest/rpcx/client
github.com/lucas-clemente/quic-go
github.com/marten-seemann/qtls-go1-18

通过 go mod graph 能够看到具体那个包的那个版本引入的

最终确认是 quic-go 的 0.27 引入的。

在 go.mod 中排除掉 quic-go 0.27 即可。在 go.mod 中加一行。

exclude lucas-clemente/quic-go v0.27.0

三. 总结和其余

  1. 为什么 go mod vendor 会更新版本,实践上只会应用 go.mod 中指定的版本;
  2. build 机器不须要 go mod vendor , 间接 go mod download 即可;
  3. go mod vendor 同 go mod download 在依赖治理上有什么不同?
退出移动版