Go Mod整洁错误消息:“但是Go 1.16会选择“
当我运行 GO MOD TIDY
时,一些软件包显示了一个错误,
> go mod tidy
github.com/myrepo/myproj imports
go.k6.io/k6 imports
go.k6.io/k6/cmd imports
github.com/fatih/color loaded from github.com/fatih/[email protected],
but go 1.16 would select v1.13.0
To upgrade to the versions selected by go 1.16:
go mod tidy -go=1.16 && go mod tidy -go=1.17
If reproducibility with go 1.16 is not needed:
go mod tidy -compat=1.17
For other options, see:
https://golang.org/doc/modules/pruning
我已安装了1.17.9。错误的含义是什么?为什么会触发它?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此错误与 Module Graph Pruning 在GO 1.17中引入。
使用GO 1.16,用于最小版本选择的模块图用于包含完整的模块图,而使用1.17的模块图仅包含速度依赖性(一些例外,请参见上面的链接)。
现在要了解触发错误的原因,您可能想查看 go 1.17发行笔记:
因此,当您运行
go mod tidy
时,它报告了go 1.16“会选择” transitive依赖项的版本(github.com/fatih/color
)这与修剪的GO 1.17的图形不同。这与构建可重复性相关,因为
go.sum
包含go.mod
和上一个的当前GO版本的校验和。如果GO 1.17并go 1.16,模块图可以有效地更改,则go.sum
将不一致。错误消息建议两个修复程序。
go mod tidy -go = 1.16&& GO MOD TIDY -GO = 1.17
- 这将依赖关系版本选择为GO 1.16,然后选择GO 1.17GO GO mod tidy -compat = 1.17
- 这简单地删除了GO 1.16 checksumss (因此,提示“不需要GO 1.16的可重复性”)。升级到1.18后,错误不应再出现自身,因为那时模块图将与GO 1.17中的相同。
This error is related to module graph pruning introduced in Go 1.17.
With Go 1.16, the module graph for Minimal Version Selection used to include the full module graph, whereas with 1.17 the graph includes only up to transitive dependencies (with some exceptions, see the link above).
Now to understand what triggers the error, you might want to look at the Go 1.17 release notes:
So when you run
go mod tidy
, it reports that Go 1.16 "would select" a version of a transitive dependency (github.com/fatih/color
) that is different from the one that the pruned graph of Go 1.17 would.This is relevant for build reproducibility, because
go.sum
contains the checksums for the current Go version specified ingo.mod
and the previous one. In case of Go 1.17 and Go 1.16 where the module graph effectively can change,go.sum
would be inconsistent.The error message suggests two fixes.
go mod tidy -go=1.16 && go mod tidy -go=1.17
— this selects the dependency versions as Go 1.16 and then as Go 1.17go mod tidy -compat=1.17
— this simply removes the Go 1.16 checksums (hence the tip "reproducibility with go 1.16 is not needed").The error should not present itself anymore after you upgrade to Go 1.18, because then the module graph will be loaded the same as in Go 1.17.
简单说明
错误
,但GO 1.16会选择
,这意味着现在使用GO 1.16(或以下)而不是GO 1.17(或更高版本)(或更高版本)在编译软件(编译二进制)的行为上存在更深的问题)。是什么引入了这个问题?:这可能完全是您无法控制的,例如,您的一个依赖项的无辜变化可以将其引入副作用。 (正如最近在
golang.org/x/oauth2
和类似世界中所看到的那样,它破坏了世界各地的许多构建。)我可以简单地避免运行
go mod mod tidy
?是的,但这对您的实际问题无关。当时对我有什么实际影响?如果您使用GO 1.16来构建或测试,则与GO 1.17+相比,程序的行为可能略有不同。您程序的汇编采用不同版本的依赖项。略有不同,但不同,这比基础算法的亲密细节更重要。
强制构建与GO 1.17(或更高)
文档的兼容性/交流,没有人应该使用GO 1.16或以下编译您的代码。
确保您的连续集成不使用1.16或以下。
在您的所有脚本,makefiles,pipelines等中
这是迁移吗?我从未使用过1.16!
您可能会认为,在
go.mod
中宣布版本go go 1.17
强制使用该版本或更高版本。即使是某些GO 1.16工具在这种情况下确实会因go.mod文件而失败。MOD文件表示1.17,但最大支持的版本为1.16
,执行该直觉。有道理,对吗?没有。残酷的现实是,某些(也许也是您也是您的)的某些代码库 用GO 1.16进行编译,或GO 1.15。核心团队不想默默地引入此类构建过程的问题。这就是为什么您面临明确保留或明确删除这种向后兼容性的决定。
替代方案:使用GO 1.16依赖关系算法
将最后一个数字撞到最大版本,因此,如果您在1.18:
后者
-go = 1.17
(或-go = -go = 1.18
) )标志声明您想将语言功能限制为1.17(或1.18)。前
-go = 1.16
仅是瞬态,并立即覆盖。那为什么需要呢?好吧,需要副作用:它在go.mod
中留下一个标记。 1.17(或1.18)看到了标记,因此,它不使用依赖性修剪的新颖算法。取而代之的是,它选择了与1.16相同的版本,并将它们持续到go.mod
中。Simple explanation
The error
but go 1.16 would select
means there is now a deeper problem with how your compiled software (compiled binary) behaves after being compiled with Go 1.16 (or below) instead of Go 1.17 (or above).What introduced this problem?: this may be entirely out of your control, for example an innocent change in one of your dependencies can introduce it as a side effect. (As recently seen with
golang.org/x/oauth2
and similar which has broken a lot of builds around the world.)Can I simply avoid running
go mod tidy
? Yes, but this does nothing about your actual problem.What is the practical impact then for me? It's that as of now you have no build reproducibility between Go 1.16 and 1.17. If you use Go 1.16 to build or test, the behavior of your program may be subtly different compared to that of Go 1.17+. The compilation of your program takes different versions of the dependencies. Very slightly different, but different, and it's more important than the intimate details of the underlying algorithm.
Force build compatibility with Go 1.17 only (or above)
Document/communicate that nobody is supposed to compile your code with Go 1.16 or below.
Make sure your continuous integration is not using Go 1.16 or below.
In all your scripts, Makefiles, pipelines, etc., change command
go mod tidy
to:Is this a migration? I have never used Go 1.16!
You might think that declaring a version
go 1.17
in yourgo.mod
enforces usage of that Go version or higher. Even some Go 1.16 tools in that case do fail withgo.mod file indicates go 1.17, but maximum supported version is 1.16
, enforcing that intuition. Makes sense, right? Nope.The brutish reality is that some codebases of that kind (and maybe yours too) can be compiled with Go 1.16 or Go 1.15 as long as the compiled module doesn't include features only added in later Go versions! The core team doesn't want to silently introduce problems for such contrived build processes. This is why you are faced with the decision to explicitly keep or explicitly drop that kind of backward compatibility.
Alternative: use the Go 1.16 dependency algorithm
bumping the last number to your max version, so if you are on 1.18:
The latter
-go=1.17
(or-go=1.18
) flag declares that you want to cap the language features at 1.17 (or 1.18).The former
-go=1.16
is only transient and immediately overwritten. Why is it needed then? Well, it is needed for a side effect: it leaves a mark ingo.mod
. The 1.17 (or 1.18) sees the mark and because of that it doesn't use the novel algorithm of dependency pruning. Instead it chooses the same versions as 1.16 would and persists them into thego.mod
.