]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: fix two-step toolchain upgrade through go install, GOTOOLCHAIN
authorRuss Cox <rsc@golang.org>
Wed, 18 Dec 2024 20:42:48 +0000 (15:42 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 19 Dec 2024 16:12:29 +0000 (08:12 -0800)
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>

src/cmd/go/internal/toolchain/select.go
src/cmd/go/testdata/script/gotoolchain_local.txt

index cbdd7a2418e1f07b8dae7e89336587ccfcadeaf7..aeab59519c7e6d7c2ac0aed7368d6ee9999d521e 100644 (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,7 +708,11 @@ 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.
-               SwitchOrFatal(ctx, err)
+               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
index db7e082db967494060f2557fb25109e30b0a44e0..8bece6ebd8439b0f97910e6a6c530d6b539ad2a7 100644 (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