GO模块有一个v2+问题

2020-09-11 21:31:05

围棋有个问题。GO模块对模块版本2或更高版本提出了奇怪的命名要求。模块v2+上的模块名称必须以主要版本ALA…结尾。/v2,此规则的沟通一直较弱。这并不明显,整个社区也不理解它。

我在当地的围棋聚会上提出了这个问题,但从来没有人听说过这条规则。他们非常怀疑这条规则是否存在。

在很长一段时间里,Go没有包含用于版本控制依赖项的内置方法。它确实包括有时有争议的获取包裹的Go Get方法。直到最近,Go Get工具还只是根据URL克隆了Packages主分支的头部,并将其放在$GOPATH中。

关于向后兼容性的极端立场经常与GO的极端立场联系在一起,人们的期望主要是,如果你出版了一个库,你应该尽可能地保持兼容性。

多年来,出现了过多的工具来填补这一空白,gopkg.in、gopkg.in、lide,甚至一度成为官方实验部门。

然而,似乎突然之间,Russ&34;RSC&34;Cox突然将VGo(又名围棋模块)作为官方围棋解决方案出现在世界上。在它的创建过程中,似乎没有来自社区的投入,这让许多人感到懊恼。

虽然dep在很大程度上是NPM之类的标准依赖项管理器,而Go模块则是一个绝对自以为是的解决方案(Go";Go";Solution)。它作为构建步骤作为语言的一部分进行处理。当您进行构建时,如果您缺少版本化依赖项,则构建工具将获取它。

依赖项要求在go.mod中列出,预期的确切版本在go.sum中。这两个文件都使用各自特定于领域的语言。PIRE的语法让人联想到围棋本身。后者是一个空格分隔的依赖版本列表,很大程度上不打算供人类使用。

构建步骤将根据需要添加到这些文件中,运行go mod tidy将清理它们。

GO模块对包开发人员提出了非常奇怪的要求。当模块达到主要版本2或更高版本时,模块名称必须以主要版本结尾。这样做的好处是它创建了一个单独的包。结果是,一个项目现在可以依赖于同一个库的多个主要版本。

例如,可以在github.com/google/go-gihub的go.mod中看到,这看起来很简单,但它还要求您更改包中的所有交叉引用。虽然不是世界末日,但它很容易出错,甚至连谷歌都错过了一些。

这种方法最大的问题是它破坏了Go的非模块感知版本中的子包。随着时间的推移,这一点变得不那么重要了,但在旧版本的围棋中,包的名称必须与它的位置完全匹配。当没有v2目录时,https://github.com/pkg/foo不能是github.com/pkg/foo/v2。围棋团队认识到了这一问题,并将基本的模块支持补丁到围棋语言的1.9.7和1.10.3版本中,以帮助简化过渡。

第二种方法和围棋团队自己推广的方法是将v1项目保留在repo的根目录中,并实际创建包含v2库的v2/子文件夹。

这感觉很奇怪,但好处是它可以与不理解模块的旧版本Go干净利落地工作。不假思索,我只知道有一个项目走了这条路,而他们似乎又走上了这条路。

无论它的价值是什么,官方围棋博客试图澄清一些情况,并发布了一篇关于它的评论。

即使作为一名经验丰富的开发人员,我也觉得这篇文章有些令人费解。对于这一要求的重要性和不同寻常之处,写下来的内容是不够容易理解的。

许多项目,包括Buildkite的终端到HTML,直到忘记处理才知道这一要求,最终发布了不完整的版本。带有go.mod文件但不遵守模块v2+规则的v2+go库对于依赖项是编译时错误。这对用户来说比不是围棋模块更糟糕。

一些项目,如GORM,通过将其2.0版本标记为远远超过1.x版本来完全回避这个问题。这是个不错的解决方案,但是闻起来很难闻。

首先,我认为围棋团队需要更好地阐明这一规则。他们需要在屋顶上尖叫。他们至少需要文档的一个部分,清楚地用外行的话来说明。

除此之外,还有来自围棋工具的警告空间。导入较旧版本的根包的子包应该会抛出警告。这是一个太容易忽略的问题。

对于GO来说,最好也是最不可能的选择是放弃该要求,并使其成为可选的。我相信这是一个可行的解决方案。想要允许用户包含多个版本的软件包可以遵循v2指南,而其他软件包则不需要这样做。

我个人推荐的一个选项是同时要求/v0和/v1,这样您就可以立即解决问题,而不是在项目中花费数年时间,但很可能永远不会发生。早点讲授大会。

当黑客新闻和Reddit上有数千条评论,但我的评论中没有一条评论时,这是我的一个小小的挫折。我要打破僵局了!