Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
mvdan opened this issue Feb 17, 2021 · 5 comments
Open

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

mvdan opened this issue Feb 17, 2021 · 5 comments
Labels
Projects
Milestone

Comments

@mvdan
Copy link
Member

@mvdan mvdan commented Feb 17, 2021

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.

@mvdan mvdan added the Proposal label Feb 17, 2021
@mvdan mvdan added this to the Proposal milestone Feb 17, 2021
mvdan added a commit to mvdan/garble-fork that referenced this issue Feb 17, 2021
This is a bit tricky right now, but will hopefully become simpler if
golang/go#44329 gets approved and implemented.

Until then, suggest ways to do it in POSIX Shell.

While at it, stop using "garble" as a verb, and just use "obfuscate".
It's a bit silly if we say "garble garbles code"; it's much more
intuitive and less repetitive to say "garble obfuscates code".

The code still says "garble X" and "X was garbled" in a few places, and
we should fix those, but at least they are not publicly visible.
@mvdan
Copy link
Member Author

@mvdan mvdan commented Feb 17, 2021

burrowers/garble#229 is an example of user-facing docs that would become simpler with this proposed change.

Loading

@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Feb 17, 2021
lu4p pushed a commit to burrowers/garble that referenced this issue Feb 17, 2021
This is a bit tricky right now, but will hopefully become simpler if
golang/go#44329 gets approved and implemented.

Until then, suggest ways to do it in POSIX Shell.

While at it, stop using "garble" as a verb, and just use "obfuscate".
It's a bit silly if we say "garble garbles code"; it's much more
intuitive and less repetitive to say "garble obfuscates code".

The code still says "garble X" and "X was garbled" in a few places, and
we should fix those, but at least they are not publicly visible.
@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Feb 17, 2021

Can the run command also setup the path or have a flag to do so?
That way we could do gotip run example.com/mycmd and then mycmd can use the correct go version.
Instead of having to do a gotip build followed by a gotip exec or maybe even a GO=gotip gotip run example.com/mycmd which I curently use. Or worse gotip exec gotip run example.com/mycmd

Loading

@dmitshur
Copy link
Contributor

@dmitshur dmitshur commented Feb 17, 2021

@AlexRouSg The existing subcommands of goX.Y.Z already do that, see CL 143545. They don't need any changes made. This proposal is about adding a new subcommand to be able to invoke arbitrary tools with the desired toolchain version, instead of today's PATH="$(goX.Y.Z env GOROOT)/bin:$PATH" tool.

Loading

@AlexRouSg
Copy link
Contributor

@AlexRouSg AlexRouSg commented Feb 17, 2021

@dmitshur ohh my bad, didn't saw that CL

Loading

@mvdan
Copy link
Member Author

@mvdan mvdan commented Feb 17, 2021

I just realised that this change would make the goX.Y wrapper commands more consistent in a way - go1.15.8 build would simply become a shortcut for go1.15.8 exec go build.

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Proposals
Incoming
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants