英文:
Upgrading old go project to work with go modules
问题
我的$GOPATH包含3个位置:
- /home/
/Documents/gotree - /home/
/Documents/perforce/modules/thirdparty/golibs - /home/
/Documents/perforce/modules/sggolibs/
这里的第一个位置是用于一般目的,第二和第三个位置是用于工作相关的库,这些库在一个perforce服务器上进行维护。最后两个库被保存在perforce中,以便公司中的任何人都可以使用这些确切版本,而不是从互联网上获取库的最新版本。
在其他位置有几个Go服务器,它们都至少使用了$GOPATH位置2和3中的一个库。
所有这些服务器都是在2、3年前编写的,不包含任何go.mod或任何包管理项。
我的问题是,我如何将所有这些服务器升级到最新版本的Go,以便它们可以与go modules一起工作,并可能将供应商目录添加到第三方库中?
如果我的问题太笼统,我表示抱歉。
英文:
My $GOPATH contains 3 locations
- /home/<user>/Documents/gotree
- /home/<user>/Documents/perforce/modules/thirdparty/golibs
- /home/<user>/Documents/perforce/modules/sggolibs/
Here location 1 is for general purposes, 2 and 3 for work-related libraries, which are maintained on one perforce server. These last two libraries are keeping in perforce so that anyone in the company should use these exact versions, not the library's latest version from internet.
In other location a couple of go servers are there, and all of them are using atleast a single library from $GOPATH location 2 and 3.
All those server are written 2,3 years ago, and does not contain any go.mod or any package management items.
My question is how do I upgrade all these servers to latest version go so that it will work with go modules, and probably a vendor directory to the thirdparty libraries?
Apologies if my question is too generic.
答案1
得分: 1
很遗憾,Perforce不是"go"命令原生支持的版本控制系统之一,因此您可能需要进行一些脚本编写或工具配置,以便将Perforce存储库中的库整合进来。
一种选择是设置一个模块代理,用于从Perforce提供依赖项,并让您的开发人员设置GOPROXY
和GONOSUMDB
环境变量,以便他们使用该代理而不是默认的(proxy.golang.org,direct
)。
请注意,Go模块会计算和存储依赖项的校验和,因此如果您修改了任何第三方依赖项,重要的是将任何修改都使用唯一的版本字符串(或不同的模块路径!),以避免与具有不同内容的上游版本冲突。(我记得Athens代理支持过滤和/或注入模块,尽管我对其功能或配置不太熟悉。)
我不知道有哪些支持Perforce的Go模块代理实现,但您可以在https://pkg.go.dev/search?q=%22module+proxy%22上进行双重检查,以确保;至少,那里列出了许多您可以用作参考的实现。该协议故意非常简单,因此实现它希望不会太费力。
另一种选择——短期内可能需要更少的工作量,但长期来看可能需要更多工作量——是在每个模块中使用replace
指令来替换每个Perforce托管的依赖项的源代码为相应的文件系统路径。您可能可以编写一个小脚本来自动化该过程;go mod edit
命令旨在支持这种脚本编写。
替换模块需要有go.mod
文件(以减少由于拼写错误而引起的混淆),因此如果您选择这种方法,您可能需要在一个或多个Perforce目录中运行go mod init
来创建它们。
使用上述任一方法,最简单的做法可能是从您的第一方存储库中尽可能少地开始使用模块:理想情况下,只在包树的根目录下运行go mod init
,然后设置您的replace
指令和/或本地代理,然后运行go mod tidy
来填充依赖关系图。
英文:
Unfortunately, Perforce is not one of the version control systems supported natively in the go
command, so you may need to apply a bit of scripting or tooling in order to slot in the libraries from your Perforce repositories.
One option is to set up a module proxy to serve the dependencies from Perforce, and have your developers set the GOPROXY
and GONOSUMDB
environment variables so that they use that proxy instead of (or in addition to) the defaults (proxy.golang.org,direct
).
Note that Go modules compute and store checksums for dependencies, so if you have modified any third-party dependencies it is important that any modifications be served with unique version strings (or different module paths!) so that they don't collide with upstream versions with different contents. (I seem to recall that the Athens proxy has support for filtering and/or injecting modules, although I'm not very familiar with its capabilities or configuration.)
I'm not aware of any Go module proxy implementations that support Perforce today, but you might double-check https://pkg.go.dev/search?q=%22module+proxy%22 to be sure; at the very least, there are a number of implementations listed there that you could use as a reference. The protocol is intentionally very simple, so implementing it hopefully wouldn't be a huge amount of work.
Another option — probably less work in the short term but more in the long term — is to use replace
directives in each module to replace the source code for each Perforce-hosted dependency with the corresponding filesystem path. You could probably write a small script to automate that process; the go mod edit
command is intended to support that kind of scripting.
Replacement modules are required to have go.mod
files (to reduce confusion due to typos), so if you opt for this approach you may need to run go mod init
in one or more of your Perforce directories to create them.
With either of the above approaches, it is probably simplest to start with as few modules as possible in your first-party repository: ideally just one at the root of your package tree. You can run go mod init
there, then set up your replace
directives and/or local proxy, then run go mod tidy
to fill in the dependency graph.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论