安装多个Go版本在如今的go get
中变得更容易了,如https://golang.org/doc/manage-install#installing-multiple中所解释的。例如,对于1.15.8:
$ go version
go version devel +2f0da6d9e2 Wed Feb 17 01:29:54 2021 +0000 linux/amd64
$ go get golang.org/dl/go1.15.8
$ go1.15.8 download
$ go1.15.8 version
go version go1.15.8 linux/amd64
这对于直接调用Go(如在终端上直接运行go1.15.8 build
或go1.15.8 test
)非常有效。
不幸的是,对于通过编译程序、脚本或makefile间接调用go
工具的使用场景来说,这还不够。那里的标准是简单地调用go
,就像在$PATH
中找到的那样。一些工具可能会理解标志或环境变量来调用不同的Go命令,但即使这是已记录的标准,我们仍然需要依赖所有工具正确实现和传播它。
$ some-tool() { echo "some-tool: $(go version)"; }
$ some-tool
some-tool: go version devel +2f0da6d9e2 Wed Feb 17 01:29:54 2021 +0000 linux/amd64
$ # how to run some-tool with go1.15.8?
我目前的解决方案是在.bashrc
中有一个函数,用于为通过golang.org/dl下载的特定Go版本设置$PATH
,并执行给定的命令:
$ withgo() {
local gocmd=go${1}
shift
PATH=$(${gocmd} env GOROOT)/bin:${PATH} "$@"
}
$ withgo 1.15.8 some-tool
some-tool: go version go1.15.8 linux/amd64
我认为这是一个相当常见的用例,所以我们应该提供一些简单的内置方法,使用像go1.15.8
这样的 Package 程序来完成同样的任务。例如,go1.15.8 exec cmd...
可以完成上面提到的withgo 1.15.8 cmd...
的功能:
$ go1.15.8 exec
usage: go1.15.8 exec [cmd args...]
Exec runs the named executable binary with the given arguments and the
environment configured so that the go tool at version 1.15.8 is available in $PATH.
For example:
go1.15.8 exec make install
我不强烈认为exec
命令的名称;它可以被命名为其他东西,如wrap
、with-path
或as-go
,只要它仍然是易于记住和输入的东西。我们应该避免一个类似于run
的名字,因为那会让人困惑。
我不认为这可以是一个需要单独下载并安装的独立程序,因为那将抵消了轻松安装golang.org/dl/...
Go版本的目的。
我也同样不认为像gvm这样的全功能"Go版本管理器"是这里的解决方案,因为它们感觉过于复杂。golang.org/dl/...
包提供了我所需的几乎一切,除了缺少的PATH
快捷方式。
我承认,与go1.15.8 exec make
相比,与go1.15.8 build
相比,感觉冗长,但我没有看到一个在保持理智和明确的同时减少字符的好方法。
cc @toothrot@dmitshur@katiehockman,特别感谢@rogpeppe审阅早期草稿。
7条答案
按热度按时间mi7gmzs61#
burrowers/garble#229 是一个示例,它将随着这个建议的更改变得更简单。
2lpgd9682#
run
命令是否也可以设置路径,或者有标志来实现这一点?这样我们就可以执行
gotip run example.com/mycmd
,然后mycmd可以使用正确的go版本。而不必先执行
gotip build
,再执行gotip exec
,甚至可能需要执行GO=gotip gotip run example.com/mycmd
(目前正在使用)。更糟糕的是,可能需要执行gotip exec gotip run example.com/mycmd
。omhiaaxx3#
@AlexRouSg 现有的
goX.Y.Z
子命令已经实现了这个功能,具体可以参考 CL 143545。它们不需要做任何修改。本提案的目的是添加一个新的子命令,以便使用所需的工具链版本调用任意工具,而不是今天的PATH="$(goX.Y.Z env GOROOT)/bin:$PATH" tool
。bakd9h0s4#
@dmitshur 哦,我的错,没看到CL。
iswrvxsc5#
我刚刚意识到这种改变会使
goX.Y
Package 器命令在某种程度上更加一致 -go1.15.8 build
将简单地成为go1.15.8 exec go build
的快捷方式。nhn9ugyo6#
@mvdan 这个问题是否有可能在Go 1.21中通过#57001解决?例如:
wlsrxk517#
有趣的想法。我认为这也可能很快使
golang.org/dl
包过时。我会开始像那样使用GOTOOLCHAIN,并在发现任何问题时报告回来。