建议:dl:为每个Go版本提供一个设置$PATH的命令

eh57zj3b  于 5个月前  发布在  Go
关注(0)|答案(7)|浏览(66)

安装多个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 buildgo1.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命令的名称;它可以被命名为其他东西,如wrapwith-pathas-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审阅早期草稿。

mi7gmzs6

mi7gmzs61#

burrowers/garble#229 是一个示例,它将随着这个建议的更改变得更简单。

2lpgd968

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

omhiaaxx

omhiaaxx3#

@AlexRouSg 现有的 goX.Y.Z 子命令已经实现了这个功能,具体可以参考 CL 143545。它们不需要做任何修改。本提案的目的是添加一个新的子命令,以便使用所需的工具链版本调用任意工具,而不是今天的 PATH="$(goX.Y.Z env GOROOT)/bin:$PATH" tool

bakd9h0s

bakd9h0s4#

@dmitshur 哦,我的错,没看到CL。

iswrvxsc

iswrvxsc5#

我刚刚意识到这种改变会使goX.Y Package 器命令在某种程度上更加一致 - go1.15.8 build将简单地成为go1.15.8 exec go build的快捷方式。

nhn9ugyo

nhn9ugyo6#

@mvdan 这个问题是否有可能在Go 1.21中通过#57001解决?例如:

$ some-tool() { echo "some-tool: $(go version)"; }
$ some-tool
some-tool: go version go1.21rc2 darwin/arm64
$ GOTOOLCHAIN=go1.16.15 some-tool  # run some-tool with go1.16.15
go: downloading go1.16.15 (darwin/arm64)
some-tool: go version go1.16.15 darwin/arm64
wlsrxk51

wlsrxk517#

有趣的想法。我认为这也可能很快使golang.org/dl包过时。我会开始像那样使用GOTOOLCHAIN,并在发现任何问题时报告回来。

相关问题