cmd/go: fix two-step toolchain upgrade through go install, GOTOOLCHAIN

If we do one upgrade because of a go install target's go.mod file,
we still might need a second upgrade to implement the GOTOOLCHAIN
minimum. Instead of allowing a two-step switch (which we were
cutting off anyway), skip the first step and go straight to the
GOTOOLCHAIN min upgrade.

Fixes #69051.

Change-Id: I16f060f473574d8b8f84c55fae2fd0cdabc8aa19
Reviewed-on: https://go-review.googlesource.com/c/go/+/637496
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Russ Cox 2024-12-18 15:42:48 -05:00
parent 4f0561f9d3
commit cb72406c36
2 changed files with 18 additions and 3 deletions

View file

@ -169,7 +169,7 @@ func Select() {
}
gotoolchain = minToolchain
if (mode == "auto" || mode == "path") && !goInstallVersion() {
if (mode == "auto" || mode == "path") && !goInstallVersion(minVers) {
// Read go.mod to find new minimum and suggested toolchain.
file, goVers, toolchain := modGoToolchain()
gover.Startup.AutoFile = file
@ -549,7 +549,7 @@ func modGoToolchain() (file, goVers, toolchain string) {
// goInstallVersion reports whether the command line is go install m@v or go run m@v.
// If so, Select must not read the go.mod or go.work file in "auto" or "path" mode.
func goInstallVersion() bool {
func goInstallVersion(minVers string) bool {
// Note: We assume there are no flags between 'go' and 'install' or 'run'.
// During testing there are some debugging flags that are accepted
// in that position, but in production go binaries there are not.
@ -708,8 +708,12 @@ func goInstallVersion() bool {
if errors.Is(err, gover.ErrTooNew) {
// Run early switch, same one go install or go run would eventually do,
// if it understood all the command-line flags.
var s Switcher
s.Error(err)
if s.TooNew != nil && gover.Compare(s.TooNew.GoVersion, minVers) > 0 {
SwitchOrFatal(ctx, err)
}
}
return true // pkg@version found
}

View file

@ -197,6 +197,17 @@ go mod edit -go=1.501 -toolchain=none
go version
stdout go1.501
# avoid two-step switch, first from install target requirement, then from GOTOOLCHAIN min
# instead, just jump directly to GOTOOLCHAIN min
env TESTGO_VERSION=go1.2.3
env GODEBUG=toolchaintrace=1
env GOTOOLCHAIN=go1.23.0+auto
! go install rsc.io/fortune/nonexist@v0.0.1
! stderr 'switching to go1.22.9'
stderr 'using go1.23.0'
env GODEBUG=
env GOTOOLCHAIN=auto
# go install m@v and go run m@v should ignore go.mod and use m@v
env TESTGO_VERSION=go1.2.3
go mod edit -go=1.999 -toolchain=go1.998