Friday, June 23, 2023

Go 1.21 will (probably) download newer toolchains on demand by default

For some time, Go modules have supported specifying the minimum version of Go required by the module in go.mod, through the go directive. Once you can have modules that specify a minimum Go version, you have a design question of what should happen when an older version of Go tries to do something with a module that says it requires a newer version of Go. Up through Go 1.20 (more or less), Go's answer was to go ahead and try anyway. Starting in Go 1.21, Go will refuse to be this optimistic, and thus Go guarantees from 1.21 onward that a module will always be processed with at least its minimum version of Go. If this isn't possible, Go will stop with a clear error about the situation.

(This behavior is backported to 1.19.11 and 1.20.6, in that starting from each of those Go will refuse to touch a module or workspace that specifies Go 1.21 or later.)

By itself this might be frustrating and awkward, so Go offers two ways out. First, Go can search through your $PATH (or non-Unix equivalent) to try to find the necessary minimum toolchain version, and then automatically switch over to executing that version. Second, if you don't have the necessary toolchain on your $PATH already, Go can download an official release for you (or what should be an official release) and then switch over to it. As of the current Go 1.21 release candidate, the 'go' command will do both of these by default, first searching your $PATH and then trying to reach out to the Internet to download a pre-built toolchain (if one exists). How this works and is controlled is covered in the pre-release documentation for Go Toolchains and the Go 1.21 draft release notes.

(How Go decides on the (potential) authenticity of this downloaded toolchain is beyond the scope of this entry.)

Not everyone is going to be happy with the idea of the 'go' command downloading and running binaries from the Internet. If this is the case for you, you need to set GOTOOLCHAIN to either 'path', if you're happy to search $PATH for the right toolchain, or 'local', if you want to turn off this behavior entirely and have 'go' just fail. Unfortunately, Go before Go 1.21rc1 can't set this through 'go env -w', so if you want to set this globally you'll need to manually create or edit your Go configuration file (you can find its location with 'go env GOENV') so that it contains:

GOTOOLCHAIN=path

(Or 'local', if you prefer.)

Or you can set a '$GOTOOLCHAIN' environment variable. In various automated build and testing environments, you may have no choice but to inject this as an environment variable.

(It's also possible to change the default behavior of a Go installation, and I wouldn't be surprised if some Linux distributions did.)

Right now this behavior of downloading newer toolchains is either difficult or impossible to trigger, since there are no newer toolchains than Go 1.21rc1. Even after later versions are released, it may be hard to trigger and rare; realistically, I suspect we're not going to see much of this before Go 1.22 comes out, although we'll have to see.

My personal opinion is that the $PATH searching is perfectly sensible as default behavior, but downloading newer toolchain binaries over the Internet is not. I believe that there are a lot of situations where people don't want this, and the current default will force everyone to start injecting settings changes into all sorts of places to turn it off. It's possible that the Go developers will change their minds about the default before the release of Go 1.21, and I hope they do. I understand the convenience of their current default, but there's a balance between convenience and other factors.

(This elaborates on a Fediverse post that was triggered by the Go 1.21 draft release notes becoming available and providing clear documentation for this new feature.)



from Hacker News https://ift.tt/iXdZQeV

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.