Skip to content

proposal: dl: provide a command to set up $PATH with each Go version #44329

Open
@mvdan

Description

@mvdan

Installing multiple Go versions is easier these days with go get, as explained in https://golang.org/doc/manage-install#installing-multiple. For example, for 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

And this works well for direct invocations of Go, like running go1.15.8 build or go1.15.8 test directly on a terminal.

Unfortunately, it's not quite enough for the use case where the go tool is called indirectly, for example via a compiled program, script, or makefile. The standard there is to simply call go as found in $PATH. Some tools might understand flags or environment variables to call a different Go command, but even if that were a documented standard, one would still have to rely on all tools properly implementing and propagating it.

$ 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?

My current solution is to have a function in .bashrc which sets up $PATH for a specific Go version downloaded via golang.org/dl, and executes the given command:

$ 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

I argue that this is a rather common use case, so we should provide some easy built-in way to accomplish the same with wrapper programs like go1.15.8. For example, go1.15.8 exec cmd... to do the equivalent of withgo 1.15.8 cmd... above:

$ 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

I don't feel strongly about the name of the exec command; it could be named something else like wrap, with-path, or as-go, as long as it remains something easy to remember and type. We should avoid a name similar to run, as that would be confusing.

I don't think this can be a separate program that one needs to go get separately, as that defeats the purpose of the easy install of golang.org/dl/... Go versions.

I similarly do not think that full-on "Go version managers" like gvm are a solution here, because they feel overkill. The golang.org/dl/... packages offer pretty much everything I need, minus the PATH shortcut.

I will admit that go1.15.8 exec make versus make feels verbose compared to go1.15.8 build versus go build, but I don't see a nice way to shave off characters while remaining sane and explicit.

cc @toothrot @dmitshur @katiehockman, and a special thanks to @rogpeppe for reviewing an early draft.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions