Skip to content

Commit 46847c6

Browse files
Bryan C. Millsgopherbot
Bryan C. Mills
authored andcommitted
cmd/go/internal/modload: skip reading go.mod files for imports in 'go mod tidy' of modules before 'go 1.21'
This eliminate a network access in 'go mod tidy' of an already-tidy module, which would otherwise be needed to fetch go.mod checksums for the test dependencies whose go.mod checksums were omitted in Go releases between Go 1.17 and 1.20 due to bug #56222. For modules between 'go 1.17' and 'go 1.20' we intentionally preserve the old 'go mod tidy' output (omitting go.sum entries for the go.mod files of test dependencies of external packages). We should also avoid performing extra sumdb lookups for checksums that would be discarded anyway. Updates #56222. Change-Id: I7f0f1c8e902db0e3414c819621c4b99052f503f0 Reviewed-on: https://go-review.googlesource.com/c/go/+/492741 Auto-Submit: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Reviewed-by: Carlos Amedee <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 8e8303e commit 46847c6

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

src/cmd/go/internal/modload/import.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,13 @@ func (e *invalidImportError) Unwrap() error {
256256
// If the package is present in exactly one module, importFromModules will
257257
// return the module, its root directory, and a list of other modules that
258258
// lexically could have provided the package but did not.
259-
func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph) (m module.Version, modroot, dir string, altMods []module.Version, err error) {
259+
//
260+
// If skipModFile is true, the go.mod file for the package is not loaded. This
261+
// allows 'go mod tidy' to preserve a minor checksum-preservation bug
262+
// (https://go.dev/issue/56222) for modules with 'go' versions between 1.17 and
263+
// 1.20, preventing unnecessary go.sum churn and network access in those
264+
// modules.
265+
func importFromModules(ctx context.Context, path string, rs *Requirements, mg *ModuleGraph, skipModFile bool) (m module.Version, modroot, dir string, altMods []module.Version, err error) {
260266
invalidf := func(format string, args ...interface{}) (module.Version, string, string, []module.Version, error) {
261267
return module.Version{}, "", "", nil, &invalidImportError{
262268
importPath: path,
@@ -442,7 +448,7 @@ func importFromModules(ctx context.Context, path string, rs *Requirements, mg *M
442448
// If the module graph is pruned and this is a test-only dependency
443449
// of a package in "all", we didn't necessarily load that file
444450
// when we read the module graph, so do it now to be sure.
445-
if cfg.BuildMod != "vendor" && mods[0].Path != "" && !MainModules.Contains(mods[0].Path) {
451+
if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !MainModules.Contains(mods[0].Path) {
446452
if _, err := goModSummary(mods[0]); err != nil {
447453
return module.Version{}, "", "", nil, err
448454
}

src/cmd/go/internal/modload/load.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,10 @@ type loader struct {
823823
// transitively *imported by* the packages and tests in the main module.)
824824
allClosesOverTests bool
825825

826+
// skipImportModFiles indicates whether we may skip loading go.mod files
827+
// for imported packages (as in 'go mod tidy' in Go 1.17–1.20).
828+
skipImportModFiles bool
829+
826830
work *par.Queue
827831

828832
// reset on each iteration
@@ -1003,6 +1007,10 @@ func loadFromRoots(ctx context.Context, params loaderParams) *loader {
10031007
// version higher than the go.mod version adds nothing.
10041008
ld.TidyCompatibleVersion = ld.GoVersion
10051009
}
1010+
1011+
if semver.Compare("v"+ld.GoVersion, tidyGoModSumVersionV) < 0 {
1012+
ld.skipImportModFiles = true
1013+
}
10061014
}
10071015

10081016
if semver.Compare("v"+ld.GoVersion, narrowAllVersionV) < 0 && !ld.UseVendorAll {
@@ -1398,7 +1406,7 @@ func (ld *loader) updateRequirements(ctx context.Context) (changed bool, err err
13981406
//
13991407
// In some sense, we can think of this as ‘upgraded the module providing
14001408
// pkg.path from "none" to a version higher than "none"’.
1401-
if _, _, _, _, err = importFromModules(ctx, pkg.path, rs, nil); err == nil {
1409+
if _, _, _, _, err = importFromModules(ctx, pkg.path, rs, nil, ld.skipImportModFiles); err == nil {
14021410
changed = true
14031411
break
14041412
}
@@ -1609,7 +1617,7 @@ func (ld *loader) preloadRootModules(ctx context.Context, rootPkgs []string) (ch
16091617
// If the main module is tidy and the package is in "all" — or if we're
16101618
// lucky — we can identify all of its imports without actually loading the
16111619
// full module graph.
1612-
m, _, _, _, err := importFromModules(ctx, path, ld.requirements, nil)
1620+
m, _, _, _, err := importFromModules(ctx, path, ld.requirements, nil, ld.skipImportModFiles)
16131621
if err != nil {
16141622
var missing *ImportMissingError
16151623
if errors.As(err, &missing) && ld.ResolveMissingImports {
@@ -1697,7 +1705,7 @@ func (ld *loader) load(ctx context.Context, pkg *loadPkg) {
16971705
}
16981706

16991707
var modroot string
1700-
pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg)
1708+
pkg.mod, modroot, pkg.dir, pkg.altMods, pkg.err = importFromModules(ctx, pkg.path, ld.requirements, mg, ld.skipImportModFiles)
17011709
if pkg.dir == "" {
17021710
return
17031711
}
@@ -1956,7 +1964,7 @@ func (ld *loader) checkTidyCompatibility(ctx context.Context, rs *Requirements)
19561964

19571965
pkg := pkg
19581966
ld.work.Add(func() {
1959-
mod, _, _, _, err := importFromModules(ctx, pkg.path, rs, mg)
1967+
mod, _, _, _, err := importFromModules(ctx, pkg.path, rs, mg, ld.skipImportModFiles)
19601968
if mod != pkg.mod {
19611969
mismatches := <-mismatchMu
19621970
mismatches[pkg] = mismatch{mod: mod, err: err}

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,24 @@ go list -f '{{if eq .ImportPath "example.com/generics"}}{{.Module.GoVersion}}{{e
3636
stdout 1.18
3737

3838

39+
# Even at go 1.20 or earlier, 'go mod tidy' shouldn't need go.mod files or
40+
# checksums that it won't record.
41+
42+
go mod tidy -go=1.20
43+
go clean -modcache # Remove checksums from the module cache, so that only go.sum is used.
44+
45+
env OLDSUMDB=$GOSUMDB
46+
env GOSUMDB=bad
47+
go mod tidy
48+
49+
env GOSUMDB=$OLDSUMDB
50+
51+
3952
# Regardless of the go version in go.mod, 'go get -t' should fetch
4053
# enough checksums to run 'go test' on the named package.
4154

4255
rm p
43-
go mod tidy
56+
go mod tidy -go=1.20
4457
go list -m all
4558
! stdout example.com/generics
4659
go get -t example.com/m2/[email protected]

0 commit comments

Comments
 (0)