Skip to content

Commit 1a22008

Browse files
committed
cmd/go: refuse to run when the main module or workspace needs a newer Go
We already refuse to build code in modules are too new (CL 476279). This is a more comprehensive check: refuse to do anything at all with modules or workspaces that are too new. Since the module or workspace is new, it may have semantics we don't understand and misinterpret well before we get to the actual building of code. For example when we switched from // +build to //go:build that changed the decision about which files go into a package, which affects the way the overall load phase runs and which errors it reports. Waiting until the building of code would miss earlier changes like that one. Leaving the test from CL 476279 alone, but it's not load-bearing anymore. For #57001. Change-Id: I8c39943db1d7ddbcb9b5cae68d80459fddd68151 Reviewed-on: https://go-review.googlesource.com/c/go/+/497435 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Russ Cox <[email protected]> Reviewed-by: Bryan Mills <[email protected]> Auto-Submit: Russ Cox <[email protected]>
1 parent 9dd0c7f commit 1a22008

File tree

5 files changed

+58
-78
lines changed

5 files changed

+58
-78
lines changed

src/cmd/go/internal/modload/init.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,9 @@ func LoadModFile(ctx context.Context) *Requirements {
698698
if err != nil {
699699
base.Fatalf("reading go.work: %v", err)
700700
}
701+
if gover.Compare(workFileGoVersion, gover.Local()) > 0 {
702+
base.Fatalf("go: %s requires go %v (running go %v)", base.ShortPath(workFilePath), workFileGoVersion, gover.Local())
703+
}
701704
for _, modRoot := range modRoots {
702705
sumFile := strings.TrimSuffix(modFilePath(modRoot), ".mod") + ".sum"
703706
modfetch.WorkspaceGoSumFiles = append(modfetch.WorkspaceGoSumFiles, sumFile)
@@ -760,6 +763,9 @@ func LoadModFile(ctx context.Context) *Requirements {
760763
base.Fatalf("go: %v", err)
761764
}
762765
}
766+
if f.Go != nil && gover.Compare(f.Go.Version, gover.Local()) > 0 {
767+
base.Fatalf("go: %s requires go %v (running go %v)", base.ShortPath(gomod), f.Go.Version, gover.Local())
768+
}
763769

764770
modFiles = append(modFiles, f)
765771
mainModule := f.Module.Mod

src/cmd/go/internal/modload/vendor.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func readVendorList(mainModule module.Version) {
4343
vendorPkgModule = make(map[string]module.Version)
4444
vendorVersion = make(map[string]string)
4545
vendorMeta = make(map[module.Version]vendorMetadata)
46-
data, err := os.ReadFile(filepath.Join(MainModules.ModRoot(mainModule), "vendor/modules.txt"))
46+
vendorFile := filepath.Join(MainModules.ModRoot(mainModule), "vendor/modules.txt")
47+
data, err := os.ReadFile(vendorFile)
4748
if err != nil {
4849
if !errors.Is(err, fs.ErrNotExist) {
4950
base.Fatalf("go: %s", err)
@@ -110,6 +111,9 @@ func readVendorList(mainModule module.Version) {
110111
if goVersion, ok := strings.CutPrefix(entry, "go "); ok {
111112
meta.GoVersion = goVersion
112113
rawGoVersion.Store(mod, meta.GoVersion)
114+
if gover.Compare(goVersion, gover.Local()) > 0 {
115+
base.Fatalf("go: %s in %s requires go %v (running go %v)", mod.Path, base.ShortPath(vendorFile), goVersion, gover.Local())
116+
}
113117
}
114118
// All other tokens are reserved for future use.
115119
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Go should refuse to build code that is too new according to go.mod.
2+
3+
# go.mod too new
4+
env GOTOOLCHAIN=local
5+
! go build .
6+
stderr '^go: go.mod requires go 1.99999 \(running go 1\..+\)$'
7+
8+
# go.mod referenced from go.work too new
9+
cp go.work.old go.work
10+
! go build .
11+
stderr '^go: go.mod requires go 1.99999 \(running go 1\..+\)$'
12+
13+
# go.work too new
14+
cp go.work.new go.work
15+
cp go.mod.old go.mod
16+
! go build .
17+
stderr '^go: go.work requires go 1.99999 \(running go 1\..+\)$'
18+
19+
# vendor too new
20+
rm go.work
21+
mv notvendor vendor
22+
! go build -mod=vendor .
23+
stderr '^go: golang.org/x/text in vendor'${/}'modules.txt requires go 1.99999 \(running go 1\..+\)$'
24+
25+
-- go.mod --
26+
module example
27+
go 1.99999
28+
29+
-- p.go --
30+
package p
31+
32+
-- go.mod.old --
33+
module example
34+
go 1.10
35+
36+
-- go.work.new --
37+
go 1.99999
38+
use .
39+
40+
-- go.work.old --
41+
go 1.10
42+
use .
43+
44+
-- notvendor/modules.txt --
45+
# golang.org/x/text v0.9.0
46+
## explicit; go 1.99999
47+
golang.org/x/text/internal/language

src/cmd/go/testdata/script/mod_load_missing_std.txt

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/cmd/go/testdata/script/mod_tidy_too_new.txt

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)