mirror of https://github.com/golang/go.git
cmd/go: don't write own toolchain line when updating go line
The Go command had a behavior of writing its own toolchain name when updating the go line in a go.mod (for example when a user runs go get go@version). This behavior was often undesirable and the toolchain line was often removed by users before checking in go.mod files (including in the x/ repos). It also led to user confusion. This change removes that behavior. A toolchain line will not be added if one wasn't present before. The toolchain line can still be removed though: the toolchain line must be at least the go version, so if the go version is increased above the toolchain version, the toolchain version will be bumped up to that go version. Then the toolchain line will then be dropped because go <version> implies toolchain <version>. Making this change slightly hurts reproducability because future go commands run on the go.mod file may be run with a different toolchain than the one that used it, but that doesn't seem to be worth the confusion the behavior resulted in. We expect this change will not have negative consequences, but it could be possible, and we would like to hear from any users that depended on the previous behavior in case we need to roll it back before the release. Fixes #65847 Change-Id: Id795b7f762e4f90ba0fa8c7935d03f32dfc8590e Reviewed-on: https://go-review.googlesource.com/c/go/+/656835 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
485480faaa
commit
a68bf75d34
|
|
@ -745,34 +745,25 @@ func UpdateWorkGoVersion(wf *modfile.WorkFile, goVers string) (changed bool) {
|
|||
|
||||
wf.AddGoStmt(goVers)
|
||||
|
||||
// We wrote a new go line. For reproducibility,
|
||||
// if the toolchain running right now is newer than the new toolchain line,
|
||||
// update the toolchain line to record the newer toolchain.
|
||||
// The user never sets the toolchain explicitly in a 'go work' command,
|
||||
// so this is only happening as a result of a go or toolchain line found
|
||||
// in a module.
|
||||
// If the toolchain running right now is a dev toolchain (like "go1.21")
|
||||
// writing 'toolchain go1.21' will not be useful, since that's not an actual
|
||||
// toolchain you can download and run. In that case fall back to at least
|
||||
// checking that the toolchain is new enough for the Go version.
|
||||
toolchain := "go" + old
|
||||
if wf.Toolchain != nil {
|
||||
toolchain = wf.Toolchain.Name
|
||||
}
|
||||
if gover.IsLang(gover.Local()) {
|
||||
toolchain = gover.ToolchainMax(toolchain, "go"+goVers)
|
||||
} else {
|
||||
toolchain = gover.ToolchainMax(toolchain, "go"+gover.Local())
|
||||
if wf.Toolchain == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// Drop the toolchain line if it is implied by the go line
|
||||
// Drop the toolchain line if it is implied by the go line,
|
||||
// if its version is older than the version in the go line,
|
||||
// or if it is asking for a toolchain older than Go 1.21,
|
||||
// which will not understand the toolchain line.
|
||||
if toolchain == "go"+goVers || gover.Compare(gover.FromToolchain(toolchain), gover.GoStrictVersion) < 0 {
|
||||
// Previously, a toolchain line set to the local toolchain
|
||||
// version was added so that future operations on the go file
|
||||
// would use the same toolchain logic for reproducibility.
|
||||
// This behavior seemed to cause user confusion without much
|
||||
// benefit so it was removed. See #65847.
|
||||
toolchain := wf.Toolchain.Name
|
||||
toolVers := gover.FromToolchain(toolchain)
|
||||
if toolchain == "go"+goVers || gover.Compare(toolVers, goVers) < 0 || gover.Compare(toolVers, gover.GoStrictVersion) < 0 {
|
||||
wf.DropToolchainStmt()
|
||||
} else {
|
||||
wf.AddToolchainStmt(toolchain)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -1833,22 +1824,7 @@ func UpdateGoModFromReqs(ctx context.Context, opts WriteOpts) (before, after []b
|
|||
toolchain = "go" + goVersion
|
||||
}
|
||||
|
||||
// For reproducibility, if we are writing a new go line,
|
||||
// and we're not explicitly modifying the toolchain line with 'go get toolchain@something',
|
||||
// and the go version is one that supports switching toolchains,
|
||||
// and the toolchain running right now is newer than the current toolchain line,
|
||||
// then update the toolchain line to record the newer toolchain.
|
||||
//
|
||||
// TODO(#57001): This condition feels too complicated. Can we simplify it?
|
||||
// TODO(#57001): Add more tests for toolchain lines.
|
||||
toolVers := gover.FromToolchain(toolchain)
|
||||
if wroteGo && !opts.DropToolchain && !opts.ExplicitToolchain &&
|
||||
gover.Compare(goVersion, gover.GoStrictVersion) >= 0 &&
|
||||
(gover.Compare(gover.Local(), toolVers) > 0 && !gover.IsLang(gover.Local())) {
|
||||
toolchain = "go" + gover.Local()
|
||||
toolVers = gover.FromToolchain(toolchain)
|
||||
}
|
||||
|
||||
if opts.DropToolchain || toolchain == "go"+goVersion || (gover.Compare(toolVers, gover.GoStrictVersion) < 0 && !opts.ExplicitToolchain) {
|
||||
// go get toolchain@none or toolchain matches go line or isn't valid; drop it.
|
||||
// TODO(#57001): 'go get' should reject explicit toolchains below GoStrictVersion.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ stderr '^go: rsc.io/future@v1.0.0: module rsc.io/future@v1.0.0 requires go >= 1.
|
|||
go get .
|
||||
stderr '^go: module rsc.io/future@v1.0.0 requires go >= 1.999; switching to go1.999testmod$'
|
||||
stderr '^go: upgraded go 1.21 => 1.999$'
|
||||
stderr '^go: added toolchain go1.999testmod$'
|
||||
! stderr '^go: added toolchain'
|
||||
|
||||
|
||||
# Now, the various 'go mod' subcommands should succeed.
|
||||
|
|
|
|||
|
|
@ -102,6 +102,4 @@ module example
|
|||
|
||||
go 1.23
|
||||
|
||||
toolchain go1.23.9
|
||||
|
||||
require rsc.io/needall v0.0.1
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ stderr '^go: rsc.io/needall@v0.0.1 requires go >= 1.23; switching to go1.23.9$'
|
|||
! stderr '\(running'
|
||||
stderr '^go: added rsc.io/needall v0.0.1'
|
||||
grep 'go 1.23' go.mod
|
||||
grep 'toolchain go1.23.9' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# GOTOOLCHAIN=min+auto should run the newer toolchain
|
||||
env GOTOOLCHAIN=go1.21+auto
|
||||
|
|
@ -19,7 +19,7 @@ stderr '^go: rsc.io/needall@v0.0.1 requires go >= 1.23; switching to go1.23.9$'
|
|||
! stderr '\(running'
|
||||
stderr '^go: added rsc.io/needall v0.0.1'
|
||||
grep 'go 1.23' go.mod
|
||||
grep 'toolchain go1.23.9' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# GOTOOLCHAIN=go1.21 should NOT run the newer toolchain
|
||||
env GOTOOLCHAIN=go1.21
|
||||
|
|
@ -67,7 +67,7 @@ cp go.mod.new go.mod
|
|||
go get go@1.22rc1
|
||||
stderr '^go: updating go.mod requires go >= 1.22rc1; switching to go1.22.9$'
|
||||
stderr '^go: upgraded go 1.1 => 1.22rc1$'
|
||||
stderr '^go: added toolchain go1.22.9$'
|
||||
! stderr '^go: added toolchain$'
|
||||
|
||||
# go get go@1.22.1 should use 1.22.1 exactly, not a later release.
|
||||
env GOTOOLCHAIN=local
|
||||
|
|
@ -80,7 +80,7 @@ cp go.mod.new go.mod
|
|||
go get go@1.22.1
|
||||
stderr '^go: updating go.mod requires go >= 1.22.1; switching to go1.22.9$'
|
||||
stderr '^go: upgraded go 1.1 => 1.22.1$'
|
||||
stderr '^go: added toolchain go1.22.9$'
|
||||
! stderr '^go: added toolchain$'
|
||||
|
||||
# go get needgo122 (says 'go 1.22') should use 1.22.0, the earliest release we have available
|
||||
# (ignoring prereleases).
|
||||
|
|
@ -94,7 +94,7 @@ cp go.mod.new go.mod
|
|||
go get rsc.io/needgo122
|
||||
stderr '^go: upgraded go 1.1 => 1.22$'
|
||||
stderr '^go: rsc.io/needgo122@v0.0.1 requires go >= 1.22; switching to go1.22.9$'
|
||||
stderr '^go: added toolchain go1.22.9$'
|
||||
! stderr '^go: added toolchain$'
|
||||
|
||||
# go get needgo1223 (says 'go 1.22.3') should use go 1.22.3
|
||||
env GOTOOLCHAIN=local
|
||||
|
|
@ -107,7 +107,7 @@ cp go.mod.new go.mod
|
|||
go get rsc.io/needgo1223
|
||||
stderr '^go: upgraded go 1.1 => 1.22.3$'
|
||||
stderr '^go: rsc.io/needgo1223@v0.0.1 requires go >= 1.22.3; switching to go1.22.9$'
|
||||
stderr '^go: added toolchain go1.22.9$'
|
||||
! stderr '^go: added toolchain$'
|
||||
|
||||
# go get needgo124 (says 'go 1.24') should use go 1.24rc1, the only version available
|
||||
env GOTOOLCHAIN=local
|
||||
|
|
@ -120,7 +120,7 @@ cp go.mod.new go.mod
|
|||
go get rsc.io/needgo124
|
||||
stderr '^go: rsc.io/needgo124@v0.0.1 requires go >= 1.24; switching to go1.24rc1$'
|
||||
stderr '^go: upgraded go 1.1 => 1.24$'
|
||||
stderr '^go: added toolchain go1.24rc1$'
|
||||
! stderr '^go: added toolchain$'
|
||||
|
||||
# The -C flag should not happen more than once due to switching.
|
||||
mkdir dir dir/dir
|
||||
|
|
@ -132,7 +132,7 @@ cp p.go dir/dir/p.go
|
|||
go get -C dir rsc.io/needgo124
|
||||
stderr '^go: rsc.io/needgo124@v0.0.1 requires go >= 1.24; switching to go1.24rc1$'
|
||||
stderr '^go: upgraded go 1.1 => 1.24$'
|
||||
stderr '^go: added toolchain go1.24rc1$'
|
||||
! stderr '^go: added toolchain1$'
|
||||
cmp go.mod.new go.mod
|
||||
cmp go.mod.new dir/dir/go.mod
|
||||
grep 'go 1.24$' dir/go.mod
|
||||
|
|
|
|||
|
|
@ -7,28 +7,28 @@ cp go.mod.orig go.mod
|
|||
go get go
|
||||
stderr '^go: upgraded go 1.21 => 1.23.9$'
|
||||
grep 'go 1.23.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# go get go@1.23 should use the latest Go 1.23
|
||||
cp go.mod.orig go.mod
|
||||
go get go@1.23
|
||||
stderr '^go: upgraded go 1.21 => 1.23.9$'
|
||||
grep 'go 1.23.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# go get go@1.22 should use the latest Go 1.22
|
||||
cp go.mod.orig go.mod
|
||||
go get go@1.22
|
||||
stderr '^go: upgraded go 1.21 => 1.22.9$'
|
||||
grep 'go 1.22.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain1 go.mod
|
||||
|
||||
# go get go@patch should use the latest patch release
|
||||
go get go@1.22.1
|
||||
go get go@patch
|
||||
stderr '^go: upgraded go 1.22.1 => 1.22.9$'
|
||||
grep 'go 1.22.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# go get go@1.24 does NOT find the release candidate
|
||||
cp go.mod.orig go.mod
|
||||
|
|
@ -40,17 +40,22 @@ cp go.mod.orig go.mod
|
|||
go get go@1.24rc1
|
||||
stderr '^go: upgraded go 1.21 => 1.24rc1$'
|
||||
grep 'go 1.24rc1' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# go get go@latest finds the latest Go 1.23
|
||||
cp go.mod.orig go.mod
|
||||
go get go@latest
|
||||
stderr '^go: upgraded go 1.21 => 1.23.9$'
|
||||
grep 'go 1.23.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
! grep toolchain go.mod
|
||||
|
||||
# Again, with toolchains.
|
||||
|
||||
go get toolchain@go1.99rc1
|
||||
stderr '^go: added toolchain go1.99rc1$'
|
||||
grep 'go 1.23.9' go.mod
|
||||
grep 'toolchain go1.99rc1' go.mod
|
||||
|
||||
# go get toolchain should find go1.999testmod.
|
||||
go get toolchain
|
||||
stderr '^go: upgraded toolchain go1.99rc1 => go1.999testmod$'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# This test verifies that 'go get' and 'go mod tidy' switch to a newer toolchain
|
||||
# if needed to process newly-reolved imports.
|
||||
# if needed to process newly-resolved imports.
|
||||
|
||||
env TESTGO_VERSION=go1.21.0
|
||||
env TESTGO_VERSION_SWITCH=switch
|
||||
|
|
@ -46,7 +46,6 @@ go: trying upgrade to example.net/b@v0.1.0
|
|||
go: accepting indirect upgrade from go@1.20 to 1.22.0
|
||||
go: trying upgrade to example.net/c@v0.1.0
|
||||
go: upgraded go 1.20 => 1.22.0
|
||||
go: added toolchain go1.22.9
|
||||
go: added example.net/b v0.1.0
|
||||
go: added example.net/c v0.1.0
|
||||
go: added example.net/d v0.1.0
|
||||
|
|
@ -67,7 +66,6 @@ go: trying upgrade to example.net/c@v0.1.0
|
|||
go: trying upgrade to example.net/d@v0.2.0
|
||||
go: accepting indirect upgrade from go@1.22.0 to 1.23.0
|
||||
go: upgraded go 1.20 => 1.23.0
|
||||
go: added toolchain go1.23.9
|
||||
go: upgraded example.net/a v0.1.0 => v0.2.0
|
||||
go: added example.net/b v0.1.0
|
||||
go: added example.net/c v0.1.0
|
||||
|
|
@ -92,8 +90,6 @@ module example
|
|||
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.22.9
|
||||
|
||||
require (
|
||||
example.net/a v0.1.0
|
||||
example.net/b v0.1.0
|
||||
|
|
@ -117,8 +113,6 @@ module example
|
|||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.9
|
||||
|
||||
require (
|
||||
example.net/a v0.2.0
|
||||
example.net/b v0.1.0
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ cmpenv go.mod go.mod.latest
|
|||
|
||||
cp go.mod.117 go.mod
|
||||
go mod tidy -go=1.21.0 # lower than $goversion
|
||||
cmpenv go.mod go.mod.121toolchain
|
||||
cmp go.mod go.mod.121toolchain
|
||||
|
||||
|
||||
-- go.mod --
|
||||
|
|
@ -334,8 +334,6 @@ module example.com/m
|
|||
|
||||
go 1.21.0
|
||||
|
||||
toolchain $TESTGO_VERSION
|
||||
|
||||
require example.net/a v0.1.0
|
||||
|
||||
require (
|
||||
|
|
|
|||
|
|
@ -18,9 +18,12 @@ grep 'toolchain go1.22.1' go.mod
|
|||
|
||||
go get go@1.22.3
|
||||
stderr '^go: upgraded go 1.10 => 1.22.3$'
|
||||
stderr '^go: upgraded toolchain go1.22.1 => go1.100.0$'
|
||||
! stderr '^go: upgraded toolchain$'
|
||||
grep 'go 1.22.3' go.mod
|
||||
|
||||
go get toolchain@go1.100.0
|
||||
stderr '^go: added toolchain go1.100.0$'
|
||||
|
||||
go get go@1.22.3 toolchain@1.22.3
|
||||
stderr '^go: removed toolchain go1.100.0$'
|
||||
! grep toolchain go.mod
|
||||
|
|
@ -65,6 +68,10 @@ stderr '^go: removed toolchain go1.23.9'
|
|||
! stderr ' go 1'
|
||||
grep 'go 1.23.5' go.mod
|
||||
|
||||
go get toolchain@go1.23.0 go@1.22.0
|
||||
go get go@1.24.0
|
||||
! grep toolchain go.mod
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
go 1.10
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# go get should update the go and toolchain lines in go.work
|
||||
# go get should update the go line in go.work
|
||||
env TESTGO_VERSION=go1.21
|
||||
env TESTGO_VERSION_SWITCH=switch
|
||||
env GOTOOLCHAIN=auto
|
||||
|
|
@ -9,8 +9,8 @@ stderr '^go: rsc.io/needall@v0.0.1 requires go >= 1.23; switching to go1.23.9$'
|
|||
stderr '^go: added rsc.io/needall v0.0.1'
|
||||
grep 'go 1.23$' go.mod
|
||||
grep 'go 1.23$' go.work
|
||||
grep 'toolchain go1.23.9' go.mod
|
||||
grep 'toolchain go1.23.9' go.work
|
||||
! grep toolchain go.mod
|
||||
! grep toolchain go.work
|
||||
|
||||
-- go.mod.new --
|
||||
module m
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ env GOTOOLCHAIN=auto
|
|||
go work sync
|
||||
stderr '^go: m1_22_1'${/}'go.mod requires go >= 1.22.1; switching to go1.22.9$'
|
||||
grep '^go 1.22.1$' go.work
|
||||
grep '^toolchain go1.22.9$' go.work
|
||||
! grep toolchain go.work
|
||||
|
||||
# work sync with newer modules should update go 1.22.1 -> 1.24rc1 and drop toolchain
|
||||
go work edit -use=./m1_24_rc0
|
||||
|
|
@ -42,4 +42,4 @@ go work sync
|
|||
stderr '^go: m1_24_rc0'${/}'go.mod requires go >= 1.24rc0; switching to go1.24rc1$'
|
||||
cat go.work
|
||||
grep '^go 1.24rc0$' go.work
|
||||
grep '^toolchain go1.24rc1$' go.work
|
||||
! grep toolchain go.work
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ env GOTOOLCHAIN=auto
|
|||
go work use ./m1_22_0
|
||||
stderr '^go: m1_22_0'${/}'go.mod requires go >= 1.22.0; switching to go1.22.9$'
|
||||
grep '^go 1.22.0$' go.work
|
||||
grep '^toolchain go1.22.9$' go.work
|
||||
! grep toolchain go.work
|
||||
|
||||
# work use with an even newer module should bump go again.
|
||||
go work use ./m1_22_1
|
||||
! stderr switching
|
||||
stderr '^go: m1_22_1'${/}'go.mod requires go >= 1.22.1; switching to go1.22.9$'
|
||||
grep '^go 1.22.1$' go.work
|
||||
grep '^toolchain go1.22.9$' go.work # unchanged
|
||||
! grep toolchain go.work
|
||||
|
||||
# work use with an even newer module should bump go and toolchain again.
|
||||
env GOTOOLCHAIN=go1.22.9
|
||||
|
|
@ -48,4 +48,4 @@ env GOTOOLCHAIN=auto
|
|||
go work use ./m1_24_rc0
|
||||
stderr '^go: m1_24_rc0'${/}'go.mod requires go >= 1.24rc0; switching to go1.24rc1$'
|
||||
grep '^go 1.24rc0$' go.work
|
||||
grep '^toolchain go1.24rc1$' go.work
|
||||
! grep 'toolchain' go.work
|
||||
|
|
|
|||
Loading…
Reference in New Issue