Go模块很棒,但是有一个小问题

Go Modules和JFrog CLI

注:这篇博文更新于2021年10月12日

大多数编程语言和工具都支持包的概念,而且大多数时候这些包都有版本。版本的伟大之处在于,无论它们是否被工具使用,它们都允许开发人员清楚地沟通构建最终产品的依赖关系。

从一开始,Go就一直在版本控制方面挣扎,这导致开发人员开始构建自己的工具,比如gb滑翔.2017年初,Go团队推出了Dep,这是Go中包管理的官方实验。从Dep和其他语言中吸取的教训导致了官方的去模块它是在Go 1.11中引入的。


你知道吗?那JFrog Xray支持审计Go项目-扫描Go包的安全漏洞和许可证合规性。


那么,问题是什么呢?

别误会,我对介绍去模块因为它解决了很多问题。它也让我们远离了丑陋的概念供应商.让我们诚实地说,谁想在他们的项目中保留每个依赖项的源的副本,冒着失去所有依赖项的风险(我们从left-pad或者让他们的同事尝试一些新版本?

这些都是Go模块解决的问题,它甚至引入了一个环境变量叫做GOPROXY它允许开发人员通过代理发送所有模块下载请求。对于那些希望保存版本缓存(而不是每次都下载依赖项)、密切关注安全性(并限制从构建服务器访问Internet)以及许多其他原因的公司来说,这本身显然是很好的。不过,有一个小问题。GOPROXY几乎无法使用。

GOPROXY的问题

目前,使用GOPROXY是一种“全有或全无”的做法。这意味着你整个依赖树中的所有依赖(包括直接的和传递的)都需要从代理服务器中解析,如果其中没有任何依赖,go客户端就会失败去注册

换句话说,如果有人用labstack /回声v3.3.5和dgrijalva / jwt-goV3.2.0正在开发中。mod文件并运行go install并设置GOPROXY变量,go客户端将失败,除非两个模块,它们请求的版本,以及它们所有的可传递依赖项,在该代理上可用。因此,除非我绝对确定我的整个依赖树可以从代理服务器解析,代理服务器可以是内部的或外部的,否则使用这种方法是行不通的。

回退

每个问题都有解决办法,对吧?没错!事实上,解决方案已经存在。一根线GolangGitHub上的存储库(由Athens团队的Aaron Schlesinger创建)概述了问题和解决方案,以允许代理仅提供某些模块。回顾前面的示例,如果代理上有两个模块中的一个可用,而另一个不可用,则构建将成功。一个模块将从代理下载,另一个模块将从版本控制系统下载。

有这样一个退路的选择将解决部分问题。一些Go模块代理,比如雅典,就能建造空去。从那些未解决的请求中删除文件,这反过来会导致其他问题。

完成解决方案

理想的解决方案是允许用户指定他们的GOPROXY,在模块不可用的情况下使用回退,最重要的是,将这些模块上传到代理。这种方法意味着只有一个开发人员下载一个模块的版本,之后,它将在代理服务器中可用,供其他开发人员和CI服务器使用。因为并不是所有的公司都允许他们的CI服务器连接到互联网,这将真正解决这个问题,并使Go模块对开发人员来说完美无瑕。如果你想知道这是什么样子,看看JFrog CLI它包含了所有这些逻辑。我想我们都同意,这是我们对语言本身的期望……