cmd/go/internal/modload: inject modfetch.Fetcher_ into commitRequirements

This commit continues the injection of the global Fetcher_ variable into
the various function calls that make use of it.  The purpose is to
prepare for the eventual removal of the global Fetcher_ variable and
eliminate global state within the modfetch package.

[git-generate]
cd src/cmd/go/internal/modload
rf '
  inject modfetch.Fetcher_ commitRequirements
  mv readModGraph.fetcher_ readModGraph.f
'

cd ../modfetch
sed -i '
  s/for _, f := range fetcher_.workspaceGoSumFiles {/for _, fn := range fetcher_.workspaceGoSumFiles {/
  s/fetcher_.sumState.w\[f\] = make(map\[module.Version\]\[\]string)/fetcher_.sumState.w[fn] = make(map[module.Version][]string)/
  s/_, err := readGoSumFile(fetcher_.sumState.w\[f\], f)/_, err := readGoSumFile(fetcher_.sumState.w[fn], fn)/
' fetch.go
rf '
  mv GoMod.fetcher_ GoMod.f
  mv GoMod Fetcher.GoMod
  mv readDiskGoMod.fetcher_ readDiskGoMod.f
  mv readDiskGoMod Fetcher.readDiskGoMod
  mv initGoSum.fetcher_ initGoSum.f
  mv initGoSum Fetcher.initGoSum
  mv HaveSum.fetcher_ HaveSum.f
  mv checkGoMod.fetcher_ checkGoMod.f
  mv checkModSum.fetcher_ checkModSum.f
  mv WriteGoSum.fetcher_ WriteGoSum.f
  mv WriteGoSum Fetcher.WriteGoSum
  mv Lookup.fetcher_ Lookup.f
  mv Lookup Fetcher.Lookup
'

Change-Id: Ifbe7d6b90b93fd65a7443434035921e6b42dea1c
Reviewed-on: https://go-review.googlesource.com/c/go/+/724241
Reviewed-by: Michael Matloob <matloob@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@google.com>
This commit is contained in:
Ian Alexander 2025-11-24 12:38:27 -05:00
parent 47baf48890
commit e96094402d
17 changed files with 135 additions and 132 deletions

View file

@ -3416,7 +3416,7 @@ func PackagesAndErrorsOutsideModule(loaderstate *modload.State, ctx context.Cont
if deprecation != "" { if deprecation != "" {
fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", rootMod.Path, modload.ShortMessage(deprecation, "")) fmt.Fprintf(os.Stderr, "go: module %s is deprecated: %s\n", rootMod.Path, modload.ShortMessage(deprecation, ""))
} }
data, err := modfetch.GoMod(ctx, rootMod.Path, rootMod.Version) data, err := modfetch.Fetcher_.GoMod(ctx, rootMod.Path, rootMod.Version)
if err != nil { if err != nil {
return nil, fmt.Errorf("%s: %w", args[0], err) return nil, fmt.Errorf("%s: %w", args[0], err)
} }

View file

@ -309,7 +309,7 @@ func (r *cachingRepo) GoMod(ctx context.Context, version string) ([]byte, error)
return r.repo(ctx).GoMod(ctx, version) return r.repo(ctx).GoMod(ctx, version)
} }
text, err := r.gomodCache.Do(version, func() ([]byte, error) { text, err := r.gomodCache.Do(version, func() ([]byte, error) {
file, text, err := readDiskGoMod(ctx, r.path, version) file, text, err := Fetcher_.readDiskGoMod(ctx, r.path, version)
if err == nil { if err == nil {
// Note: readDiskGoMod already called checkGoMod. // Note: readDiskGoMod already called checkGoMod.
return text, nil return text, nil
@ -317,7 +317,7 @@ func (r *cachingRepo) GoMod(ctx context.Context, version string) ([]byte, error)
text, err = r.repo(ctx).GoMod(ctx, version) text, err = r.repo(ctx).GoMod(ctx, version)
if err == nil { if err == nil {
if err := checkGoMod(r.path, version, text); err != nil { if err := checkGoMod(Fetcher_, r.path, version, text); err != nil {
return text, err return text, err
} }
if err := writeDiskGoMod(ctx, file, text); err != nil { if err := writeDiskGoMod(ctx, file, text); err != nil {
@ -353,7 +353,7 @@ func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, erro
var info *RevInfo var info *RevInfo
var err2info map[error]*RevInfo var err2info map[error]*RevInfo
err := TryProxies(func(proxy string) error { err := TryProxies(func(proxy string) error {
i, err := Lookup(ctx, proxy, path).Stat(ctx, version) i, err := Fetcher_.Lookup(ctx, proxy, path).Stat(ctx, version)
if err == nil { if err == nil {
info = i info = i
} else { } else {
@ -379,7 +379,7 @@ func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, erro
// GoMod is like Lookup(ctx, path).GoMod(rev) but avoids the // GoMod is like Lookup(ctx, path).GoMod(rev) but avoids the
// repository path resolution in Lookup if the result is // repository path resolution in Lookup if the result is
// already cached on local disk. // already cached on local disk.
func GoMod(ctx context.Context, path, rev string) ([]byte, error) { func (f *Fetcher) GoMod(ctx context.Context, path, rev string) ([]byte, error) {
// Convert commit hash to pseudo-version // Convert commit hash to pseudo-version
// to increase cache hit rate. // to increase cache hit rate.
if !gover.ModIsValid(path, rev) { if !gover.ModIsValid(path, rev) {
@ -390,7 +390,7 @@ func GoMod(ctx context.Context, path, rev string) ([]byte, error) {
return nil, err return nil, err
} }
err := TryProxies(func(proxy string) error { err := TryProxies(func(proxy string) error {
info, err := Lookup(ctx, proxy, path).Stat(ctx, rev) info, err := f.Lookup(ctx, proxy, path).Stat(ctx, rev)
if err == nil { if err == nil {
rev = info.Version rev = info.Version
} }
@ -402,13 +402,13 @@ func GoMod(ctx context.Context, path, rev string) ([]byte, error) {
} }
} }
_, data, err := readDiskGoMod(ctx, path, rev) _, data, err := f.readDiskGoMod(ctx, path, rev)
if err == nil { if err == nil {
return data, nil return data, nil
} }
err = TryProxies(func(proxy string) (err error) { err = TryProxies(func(proxy string) (err error) {
data, err = Lookup(ctx, proxy, path).GoMod(ctx, rev) data, err = f.Lookup(ctx, proxy, path).GoMod(ctx, rev)
return err return err
}) })
return data, err return data, err
@ -420,7 +420,7 @@ func GoModFile(ctx context.Context, path, version string) (string, error) {
if !gover.ModIsValid(path, version) { if !gover.ModIsValid(path, version) {
return "", fmt.Errorf("invalid version %q", version) return "", fmt.Errorf("invalid version %q", version)
} }
if _, err := GoMod(ctx, path, version); err != nil { if _, err := Fetcher_.GoMod(ctx, path, version); err != nil {
return "", err return "", err
} }
// GoMod should have populated the disk cache for us. // GoMod should have populated the disk cache for us.
@ -437,7 +437,7 @@ func GoModSum(ctx context.Context, path, version string) (string, error) {
if !gover.ModIsValid(path, version) { if !gover.ModIsValid(path, version) {
return "", fmt.Errorf("invalid version %q", version) return "", fmt.Errorf("invalid version %q", version)
} }
data, err := GoMod(ctx, path, version) data, err := Fetcher_.GoMod(ctx, path, version)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -565,7 +565,7 @@ var oldVgoPrefix = []byte("//vgo 0.0.")
// returning the name of the cache file and the result. // returning the name of the cache file and the result.
// If the read fails, the caller can use // If the read fails, the caller can use
// writeDiskGoMod(file, data) to write a new cache entry. // writeDiskGoMod(file, data) to write a new cache entry.
func readDiskGoMod(ctx context.Context, path, rev string) (file string, data []byte, err error) { func (f *Fetcher) readDiskGoMod(ctx context.Context, path, rev string) (file string, data []byte, err error) {
if gover.IsToolchain(path) { if gover.IsToolchain(path) {
return "", nil, errNotCached return "", nil, errNotCached
} }
@ -578,7 +578,7 @@ func readDiskGoMod(ctx context.Context, path, rev string) (file string, data []b
} }
if err == nil { if err == nil {
if err := checkGoMod(path, rev, data); err != nil { if err := checkGoMod(f, path, rev, data); err != nil {
return "", nil, err return "", nil, err
} }
} }

View file

@ -603,7 +603,7 @@ func TestCodeRepo(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
repo := Lookup(ctx, "direct", tt.path) repo := Fetcher_.Lookup(ctx, "direct", tt.path)
if tt.mpath == "" { if tt.mpath == "" {
tt.mpath = tt.path tt.mpath = tt.path
@ -831,7 +831,7 @@ func TestCodeRepoVersions(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
repo := Lookup(ctx, "direct", tt.path) repo := Fetcher_.Lookup(ctx, "direct", tt.path)
list, err := repo.Versions(ctx, tt.prefix) list, err := repo.Versions(ctx, tt.prefix)
if err != nil { if err != nil {
t.Fatalf("Versions(%q): %v", tt.prefix, err) t.Fatalf("Versions(%q): %v", tt.prefix, err)
@ -909,7 +909,7 @@ func TestLatest(t *testing.T) {
} }
ctx := context.Background() ctx := context.Background()
repo := Lookup(ctx, "direct", tt.path) repo := Fetcher_.Lookup(ctx, "direct", tt.path)
info, err := repo.Latest(ctx) info, err := repo.Latest(ctx)
if err != nil { if err != nil {
if tt.err != "" { if tt.err != "" {

View file

@ -210,7 +210,7 @@ func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err e
// Return early if the zip and ziphash files exist. // Return early if the zip and ziphash files exist.
if _, err := os.Stat(zipfile); err == nil { if _, err := os.Stat(zipfile); err == nil {
if _, err := os.Stat(ziphashfile); err == nil { if _, err := os.Stat(ziphashfile); err == nil {
if !HaveSum(mod) { if !HaveSum(Fetcher_, mod) {
checkMod(ctx, mod) checkMod(ctx, mod)
} }
return zipfile, nil return zipfile, nil
@ -305,7 +305,7 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e
if unrecoverableErr != nil { if unrecoverableErr != nil {
return unrecoverableErr return unrecoverableErr
} }
repo := Lookup(ctx, proxy, mod.Path) repo := Fetcher_.Lookup(ctx, proxy, mod.Path)
err := repo.Zip(ctx, f, mod.Version) err := repo.Zip(ctx, f, mod.Version)
if err != nil { if err != nil {
// Zip may have partially written to f before failing. // Zip may have partially written to f before failing.
@ -372,7 +372,7 @@ func hashZip(mod module.Version, zipfile, ziphashfile string) (err error) {
if err != nil { if err != nil {
return err return err
} }
if err := checkModSum(mod, hash); err != nil { if err := checkModSum(Fetcher_, mod, hash); err != nil {
return err return err
} }
hf, err := lockedfile.Create(ziphashfile) hf, err := lockedfile.Create(ziphashfile)
@ -542,28 +542,28 @@ func SetState(newState *Fetcher) (oldState *Fetcher) {
// The boolean it returns reports whether the // The boolean it returns reports whether the
// use of go.sum is now enabled. // use of go.sum is now enabled.
// The goSum lock must be held. // The goSum lock must be held.
func initGoSum() (bool, error) { func (f *Fetcher) initGoSum() (bool, error) {
if Fetcher_.goSumFile == "" { if f.goSumFile == "" {
return false, nil return false, nil
} }
if Fetcher_.sumState.m != nil { if f.sumState.m != nil {
return true, nil return true, nil
} }
Fetcher_.sumState.m = make(map[module.Version][]string) f.sumState.m = make(map[module.Version][]string)
Fetcher_.sumState.status = make(map[modSum]modSumStatus) f.sumState.status = make(map[modSum]modSumStatus)
Fetcher_.sumState.w = make(map[string]map[module.Version][]string) f.sumState.w = make(map[string]map[module.Version][]string)
for _, f := range Fetcher_.workspaceGoSumFiles { for _, fn := range f.workspaceGoSumFiles {
Fetcher_.sumState.w[f] = make(map[module.Version][]string) f.sumState.w[fn] = make(map[module.Version][]string)
_, err := readGoSumFile(Fetcher_.sumState.w[f], f) _, err := readGoSumFile(f.sumState.w[fn], fn)
if err != nil { if err != nil {
return false, err return false, err
} }
} }
enabled, err := readGoSumFile(Fetcher_.sumState.m, Fetcher_.goSumFile) enabled, err := readGoSumFile(f.sumState.m, f.goSumFile)
Fetcher_.sumState.enabled = enabled f.sumState.enabled = enabled
return enabled, err return enabled, err
} }
@ -632,28 +632,28 @@ func readGoSum(dst map[module.Version][]string, file string, data []byte) {
// The entry's hash must be generated with a known hash algorithm. // The entry's hash must be generated with a known hash algorithm.
// mod.Version may have a "/go.mod" suffix to distinguish sums for // mod.Version may have a "/go.mod" suffix to distinguish sums for
// .mod and .zip files. // .mod and .zip files.
func HaveSum(mod module.Version) bool { func HaveSum(f *Fetcher, mod module.Version) bool {
Fetcher_.mu.Lock() f.mu.Lock()
defer Fetcher_.mu.Unlock() defer f.mu.Unlock()
inited, err := initGoSum() inited, err := f.initGoSum()
if err != nil || !inited { if err != nil || !inited {
return false return false
} }
for _, goSums := range Fetcher_.sumState.w { for _, goSums := range f.sumState.w {
for _, h := range goSums[mod] { for _, h := range goSums[mod] {
if !strings.HasPrefix(h, "h1:") { if !strings.HasPrefix(h, "h1:") {
continue continue
} }
if !Fetcher_.sumState.status[modSum{mod, h}].dirty { if !f.sumState.status[modSum{mod, h}].dirty {
return true return true
} }
} }
} }
for _, h := range Fetcher_.sumState.m[mod] { for _, h := range f.sumState.m[mod] {
if !strings.HasPrefix(h, "h1:") { if !strings.HasPrefix(h, "h1:") {
continue continue
} }
if !Fetcher_.sumState.status[modSum{mod, h}].dirty { if !f.sumState.status[modSum{mod, h}].dirty {
return true return true
} }
} }
@ -669,7 +669,7 @@ func HaveSum(mod module.Version) bool {
func RecordedSum(mod module.Version) (sum string, ok bool) { func RecordedSum(mod module.Version) (sum string, ok bool) {
Fetcher_.mu.Lock() Fetcher_.mu.Lock()
defer Fetcher_.mu.Unlock() defer Fetcher_.mu.Unlock()
inited, err := initGoSum() inited, err := Fetcher_.initGoSum()
foundSum := "" foundSum := ""
if err != nil || !inited { if err != nil || !inited {
return "", false return "", false
@ -730,7 +730,7 @@ func checkMod(ctx context.Context, mod module.Version) {
base.Fatalf("verifying %v", module.VersionError(mod, fmt.Errorf("unexpected ziphash: %q", h))) base.Fatalf("verifying %v", module.VersionError(mod, fmt.Errorf("unexpected ziphash: %q", h)))
} }
if err := checkModSum(mod, h); err != nil { if err := checkModSum(Fetcher_, mod, h); err != nil {
base.Fatalf("%s", err) base.Fatalf("%s", err)
} }
} }
@ -744,39 +744,39 @@ func goModSum(data []byte) (string, error) {
// checkGoMod checks the given module's go.mod checksum; // checkGoMod checks the given module's go.mod checksum;
// data is the go.mod content. // data is the go.mod content.
func checkGoMod(path, version string, data []byte) error { func checkGoMod(f *Fetcher, path, version string, data []byte) error {
h, err := goModSum(data) h, err := goModSum(data)
if err != nil { if err != nil {
return &module.ModuleError{Path: path, Version: version, Err: fmt.Errorf("verifying go.mod: %v", err)} return &module.ModuleError{Path: path, Version: version, Err: fmt.Errorf("verifying go.mod: %v", err)}
} }
return checkModSum(module.Version{Path: path, Version: version + "/go.mod"}, h) return checkModSum(f, module.Version{Path: path, Version: version + "/go.mod"}, h)
} }
// checkModSum checks that the recorded checksum for mod is h. // checkModSum checks that the recorded checksum for mod is h.
// //
// mod.Version may have the additional suffix "/go.mod" to request the checksum // mod.Version may have the additional suffix "/go.mod" to request the checksum
// for the module's go.mod file only. // for the module's go.mod file only.
func checkModSum(mod module.Version, h string) error { func checkModSum(f *Fetcher, mod module.Version, h string) error {
// We lock goSum when manipulating it, // We lock goSum when manipulating it,
// but we arrange to release the lock when calling checkSumDB, // but we arrange to release the lock when calling checkSumDB,
// so that parallel calls to checkModHash can execute parallel calls // so that parallel calls to checkModHash can execute parallel calls
// to checkSumDB. // to checkSumDB.
// Check whether mod+h is listed in go.sum already. If so, we're done. // Check whether mod+h is listed in go.sum already. If so, we're done.
Fetcher_.mu.Lock() f.mu.Lock()
inited, err := initGoSum() inited, err := f.initGoSum()
if err != nil { if err != nil {
Fetcher_.mu.Unlock() f.mu.Unlock()
return err return err
} }
done := inited && haveModSumLocked(Fetcher_, mod, h) done := inited && haveModSumLocked(f, mod, h)
if inited { if inited {
st := Fetcher_.sumState.status[modSum{mod, h}] st := f.sumState.status[modSum{mod, h}]
st.used = true st.used = true
Fetcher_.sumState.status[modSum{mod, h}] = st f.sumState.status[modSum{mod, h}] = st
} }
Fetcher_.mu.Unlock() f.mu.Unlock()
if done { if done {
return nil return nil
@ -793,12 +793,12 @@ func checkModSum(mod module.Version, h string) error {
// Add mod+h to go.sum, if it hasn't appeared already. // Add mod+h to go.sum, if it hasn't appeared already.
if inited { if inited {
Fetcher_.mu.Lock() f.mu.Lock()
addModSumLocked(Fetcher_, mod, h) addModSumLocked(f, mod, h)
st := Fetcher_.sumState.status[modSum{mod, h}] st := f.sumState.status[modSum{mod, h}]
st.dirty = true st.dirty = true
Fetcher_.sumState.status[modSum{mod, h}] = st f.sumState.status[modSum{mod, h}] = st
Fetcher_.mu.Unlock() f.mu.Unlock()
} }
return nil return nil
} }
@ -923,12 +923,12 @@ var ErrGoSumDirty = errors.New("updates to go.sum needed, disabled by -mod=reado
// It should have entries for both module content sums and go.mod sums // It should have entries for both module content sums and go.mod sums
// (version ends with "/go.mod"). Existing sums will be preserved unless they // (version ends with "/go.mod"). Existing sums will be preserved unless they
// have been marked for deletion with TrimGoSum. // have been marked for deletion with TrimGoSum.
func WriteGoSum(ctx context.Context, keep map[module.Version]bool, readonly bool) error { func (f *Fetcher) WriteGoSum(ctx context.Context, keep map[module.Version]bool, readonly bool) error {
Fetcher_.mu.Lock() f.mu.Lock()
defer Fetcher_.mu.Unlock() defer f.mu.Unlock()
// If we haven't read the go.sum file yet, don't bother writing it. // If we haven't read the go.sum file yet, don't bother writing it.
if !Fetcher_.sumState.enabled { if !f.sumState.enabled {
return nil return nil
} }
@ -937,9 +937,9 @@ func WriteGoSum(ctx context.Context, keep map[module.Version]bool, readonly bool
// just return without opening go.sum. // just return without opening go.sum.
dirty := false dirty := false
Outer: Outer:
for m, hs := range Fetcher_.sumState.m { for m, hs := range f.sumState.m {
for _, h := range hs { for _, h := range hs {
st := Fetcher_.sumState.status[modSum{m, h}] st := f.sumState.status[modSum{m, h}]
if st.dirty && (!st.used || keep[m]) { if st.dirty && (!st.used || keep[m]) {
dirty = true dirty = true
break Outer break Outer
@ -952,7 +952,7 @@ Outer:
if readonly { if readonly {
return ErrGoSumDirty return ErrGoSumDirty
} }
if fsys.Replaced(Fetcher_.goSumFile) { if fsys.Replaced(f.goSumFile) {
base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay") base.Fatalf("go: updates to go.sum needed, but go.sum is part of the overlay specified with -overlay")
} }
@ -962,16 +962,16 @@ Outer:
defer unlock() defer unlock()
} }
err := lockedfile.Transform(Fetcher_.goSumFile, func(data []byte) ([]byte, error) { err := lockedfile.Transform(f.goSumFile, func(data []byte) ([]byte, error) {
tidyGoSum := tidyGoSum(Fetcher_, data, keep) tidyGoSum := tidyGoSum(f, data, keep)
return tidyGoSum, nil return tidyGoSum, nil
}) })
if err != nil { if err != nil {
return fmt.Errorf("updating go.sum: %w", err) return fmt.Errorf("updating go.sum: %w", err)
} }
Fetcher_.sumState.status = make(map[modSum]modSumStatus) f.sumState.status = make(map[modSum]modSumStatus)
Fetcher_.sumState.overwrite = false f.sumState.overwrite = false
return nil return nil
} }
@ -1044,7 +1044,7 @@ func sumInWorkspaceModulesLocked(f *Fetcher, m module.Version) bool {
func TrimGoSum(keep map[module.Version]bool) { func TrimGoSum(keep map[module.Version]bool) {
Fetcher_.mu.Lock() Fetcher_.mu.Lock()
defer Fetcher_.mu.Unlock() defer Fetcher_.mu.Unlock()
inited, err := initGoSum() inited, err := Fetcher_.initGoSum()
if err != nil { if err != nil {
base.Fatalf("%s", err) base.Fatalf("%s", err)
} }

View file

@ -200,14 +200,14 @@ type lookupCacheKey struct {
// //
// A successful return does not guarantee that the module // A successful return does not guarantee that the module
// has any defined versions. // has any defined versions.
func Lookup(ctx context.Context, proxy, path string) Repo { func (f *Fetcher) Lookup(ctx context.Context, proxy, path string) Repo {
if traceRepo { if traceRepo {
defer logCall("Lookup(%q, %q)", proxy, path)() defer logCall("Lookup(%q, %q)", proxy, path)()
} }
return Fetcher_.lookupCache.Do(lookupCacheKey{proxy, path}, func() Repo { return f.lookupCache.Do(lookupCacheKey{proxy, path}, func() Repo {
return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) { return newCachingRepo(ctx, path, func(ctx context.Context) (Repo, error) {
r, err := lookup(ctx, proxy, path) r, err := lookup(f, ctx, proxy, path)
if err == nil && traceRepo { if err == nil && traceRepo {
r = newLoggingRepo(r) r = newLoggingRepo(r)
} }
@ -248,14 +248,14 @@ func LookupLocal(ctx context.Context, codeRoot string, path string, dir string)
} }
// lookup returns the module with the given module path. // lookup returns the module with the given module path.
func lookup(ctx context.Context, proxy, path string) (r Repo, err error) { func lookup(fetcher_ *Fetcher, ctx context.Context, proxy, path string) (r Repo, err error) {
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
return nil, errLookupDisabled return nil, errLookupDisabled
} }
switch path { switch path {
case "go", "toolchain": case "go", "toolchain":
return &toolchainRepo{path, Lookup(ctx, proxy, "golang.org/toolchain")}, nil return &toolchainRepo{path, fetcher_.Lookup(ctx, proxy, "golang.org/toolchain")}, nil
} }
if module.MatchPrefixPatterns(cfg.GONOPROXY, path) { if module.MatchPrefixPatterns(cfg.GONOPROXY, path) {

View file

@ -1788,7 +1788,7 @@ func (r *resolver) checkPackageProblems(loaderstate *modload.State, ctx context.
if oldRepl := modload.Replacement(loaderstate, old); oldRepl.Path != "" { if oldRepl := modload.Replacement(loaderstate, old); oldRepl.Path != "" {
oldActual = oldRepl oldActual = oldRepl
} }
if mActual == oldActual || mActual.Version == "" || !modfetch.HaveSum(oldActual) { if mActual == oldActual || mActual.Version == "" || !modfetch.HaveSum(modfetch.Fetcher_, oldActual) {
continue continue
} }
r.work.Add(func() { r.work.Add(func() {

View file

@ -103,7 +103,7 @@ func ModuleInfo(loaderstate *State, ctx context.Context, path string) *modinfo.M
v, ok = rs.rootSelected(loaderstate, path) v, ok = rs.rootSelected(loaderstate, path)
} }
if !ok { if !ok {
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
base.Fatal(err) base.Fatal(err)
} }
@ -329,7 +329,7 @@ func moduleInfo(loaderstate *State, ctx context.Context, rs *Requirements, m mod
checksumOk := func(suffix string) bool { checksumOk := func(suffix string) bool {
return rs == nil || m.Version == "" || !mustHaveSums(loaderstate) || return rs == nil || m.Version == "" || !mustHaveSums(loaderstate) ||
modfetch.HaveSum(module.Version{Path: m.Path, Version: m.Version + suffix}) modfetch.HaveSum(modfetch.Fetcher_, module.Version{Path: m.Path, Version: m.Version + suffix})
} }
mod := module.Version{Path: m.Path, Version: m.Version} mod := module.Version{Path: m.Path, Version: m.Version}
@ -355,7 +355,7 @@ func moduleInfo(loaderstate *State, ctx context.Context, rs *Requirements, m mod
if m.GoVersion == "" && checksumOk("/go.mod") { if m.GoVersion == "" && checksumOk("/go.mod") {
// Load the go.mod file to determine the Go version, since it hasn't // Load the go.mod file to determine the Go version, since it hasn't
// already been populated from rawGoVersion. // already been populated from rawGoVersion.
if summary, err := rawGoModSummary(loaderstate, mod); err == nil && summary.goVersion != "" { if summary, err := rawGoModSummary(modfetch.Fetcher_, loaderstate, mod); err == nil && summary.goVersion != "" {
m.GoVersion = summary.goVersion m.GoVersion = summary.goVersion
} }
} }

View file

@ -20,6 +20,7 @@ import (
"cmd/go/internal/base" "cmd/go/internal/base"
"cmd/go/internal/cfg" "cmd/go/internal/cfg"
"cmd/go/internal/gover" "cmd/go/internal/gover"
"cmd/go/internal/modfetch"
"cmd/go/internal/mvs" "cmd/go/internal/mvs"
"cmd/internal/par" "cmd/internal/par"
@ -269,9 +270,9 @@ func (rs *Requirements) hasRedundantRoot(loaderstate *State) bool {
// //
// If the requirements of any relevant module fail to load, Graph also // If the requirements of any relevant module fail to load, Graph also
// returns a non-nil error of type *mvs.BuildListError. // returns a non-nil error of type *mvs.BuildListError.
func (rs *Requirements) Graph(loaderstate *State, ctx context.Context) (*ModuleGraph, error) { func (rs *Requirements) Graph(fetcher_ *modfetch.Fetcher, loaderstate *State, ctx context.Context) (*ModuleGraph, error) {
rs.graphOnce.Do(func() { rs.graphOnce.Do(func() {
mg, mgErr := readModGraph(loaderstate, ctx, rs.pruning, rs.rootModules, nil) mg, mgErr := readModGraph(fetcher_, loaderstate, ctx, rs.pruning, rs.rootModules, nil)
rs.graph.Store(&cachedGraph{mg, mgErr}) rs.graph.Store(&cachedGraph{mg, mgErr})
}) })
cached := rs.graph.Load() cached := rs.graph.Load()
@ -307,7 +308,7 @@ var readModGraphDebugOnce sync.Once
// //
// Unlike LoadModGraph, readModGraph does not attempt to diagnose or update // Unlike LoadModGraph, readModGraph does not attempt to diagnose or update
// inconsistent roots. // inconsistent roots.
func readModGraph(loaderstate *State, ctx context.Context, pruning modPruning, roots []module.Version, unprune map[module.Version]bool) (*ModuleGraph, error) { func readModGraph(f *modfetch.Fetcher, loaderstate *State, ctx context.Context, pruning modPruning, roots []module.Version, unprune map[module.Version]bool) (*ModuleGraph, error) {
mustHaveGoRoot(roots) mustHaveGoRoot(roots)
if pruning == pruned { if pruning == pruned {
// Enable diagnostics for lazy module loading // Enable diagnostics for lazy module loading
@ -367,7 +368,7 @@ func readModGraph(loaderstate *State, ctx context.Context, pruning modPruning, r
// m's go.mod file indicates that it supports graph pruning. // m's go.mod file indicates that it supports graph pruning.
loadOne := func(m module.Version) (*modFileSummary, error) { loadOne := func(m module.Version) (*modFileSummary, error) {
return mg.loadCache.Do(m, func() (*modFileSummary, error) { return mg.loadCache.Do(m, func() (*modFileSummary, error) {
summary, err := goModSummary(loaderstate, m) summary, err := goModSummary(f, loaderstate, m)
mu.Lock() mu.Lock()
if err == nil { if err == nil {
@ -572,7 +573,7 @@ func LoadModGraph(loaderstate *State, ctx context.Context, goVersion string) (*M
rs = newRequirements(loaderstate, unpruned, rs.rootModules, rs.direct) rs = newRequirements(loaderstate, unpruned, rs.rootModules, rs.direct)
} }
return rs.Graph(loaderstate, ctx) return rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
} }
rs, mg, err := expandGraph(loaderstate, ctx, rs) rs, mg, err := expandGraph(loaderstate, ctx, rs)
@ -595,7 +596,7 @@ func LoadModGraph(loaderstate *State, ctx context.Context, goVersion string) (*M
// expandGraph returns non-nil requirements and a non-nil graph regardless of // expandGraph returns non-nil requirements and a non-nil graph regardless of
// errors. On error, the roots might not be updated to be consistent. // errors. On error, the roots might not be updated to be consistent.
func expandGraph(loaderstate *State, ctx context.Context, rs *Requirements) (*Requirements, *ModuleGraph, error) { func expandGraph(loaderstate *State, ctx context.Context, rs *Requirements) (*Requirements, *ModuleGraph, error) {
mg, mgErr := rs.Graph(loaderstate, ctx) mg, mgErr := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if mgErr != nil { if mgErr != nil {
// Without the graph, we can't update the roots: we don't know which // Without the graph, we can't update the roots: we don't know which
// versions of transitive dependencies would be selected. // versions of transitive dependencies would be selected.
@ -617,7 +618,7 @@ func expandGraph(loaderstate *State, ctx context.Context, rs *Requirements) (*Re
return rs, mg, rsErr return rs, mg, rsErr
} }
rs = newRS rs = newRS
mg, mgErr = rs.Graph(loaderstate, ctx) mg, mgErr = rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
} }
return rs, mg, mgErr return rs, mg, mgErr
@ -859,7 +860,7 @@ func tidyPrunedRoots(loaderstate *State, ctx context.Context, mainModule module.
for len(queue) > 0 { for len(queue) > 0 {
roots = tidy.rootModules roots = tidy.rootModules
mg, err := tidy.Graph(loaderstate, ctx) mg, err := tidy.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -897,7 +898,7 @@ func tidyPrunedRoots(loaderstate *State, ctx context.Context, mainModule module.
} }
roots = tidy.rootModules roots = tidy.rootModules
_, err := tidy.Graph(loaderstate, ctx) _, err := tidy.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -939,7 +940,7 @@ func tidyPrunedRoots(loaderstate *State, ctx context.Context, mainModule module.
if len(roots) > len(tidy.rootModules) { if len(roots) > len(tidy.rootModules) {
module.Sort(roots) module.Sort(roots)
tidy = newRequirements(loaderstate, pruned, roots, tidy.direct) tidy = newRequirements(loaderstate, pruned, roots, tidy.direct)
_, err = tidy.Graph(loaderstate, ctx) _, err = tidy.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1121,7 +1122,7 @@ func updatePrunedRoots(loaderstate *State, ctx context.Context, direct map[strin
rs = newRequirements(loaderstate, pruned, roots, direct) rs = newRequirements(loaderstate, pruned, roots, direct)
var err error var err error
mg, err = rs.Graph(loaderstate, ctx) mg, err = rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return rs, err return rs, err
} }
@ -1135,7 +1136,7 @@ func updatePrunedRoots(loaderstate *State, ctx context.Context, direct map[strin
// We've already loaded the full module graph, which includes the // We've already loaded the full module graph, which includes the
// requirements of all of the root modules — even the transitive // requirements of all of the root modules — even the transitive
// requirements, if they are unpruned! // requirements, if they are unpruned!
mg, _ = rs.Graph(loaderstate, ctx) mg, _ = rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
} else if cfg.BuildMod == "vendor" { } else if cfg.BuildMod == "vendor" {
// We can't spot-check the requirements of other modules because we // We can't spot-check the requirements of other modules because we
// don't in general have their go.mod files available in the vendor // don't in general have their go.mod files available in the vendor
@ -1148,7 +1149,7 @@ func updatePrunedRoots(loaderstate *State, ctx context.Context, direct map[strin
// inconsistent in some way; we need to load the full module graph // inconsistent in some way; we need to load the full module graph
// so that we can fix the roots properly. // so that we can fix the roots properly.
var err error var err error
mg, err = rs.Graph(loaderstate, ctx) mg, err = rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return rs, err return rs, err
} }
@ -1235,7 +1236,7 @@ func spotCheckRoots(loaderstate *State, ctx context.Context, rs *Requirements, m
return return
} }
summary, err := goModSummary(loaderstate, m) summary, err := goModSummary(modfetch.Fetcher_, loaderstate, m)
if err != nil { if err != nil {
cancel() cancel()
return return
@ -1368,7 +1369,7 @@ func tidyUnprunedRoots(loaderstate *State, ctx context.Context, mainModule modul
// 4. Every version in add is selected at its given version unless upgraded by // 4. Every version in add is selected at its given version unless upgraded by
// (the dependencies of) an existing root or another module in add. // (the dependencies of) an existing root or another module in add.
func updateUnprunedRoots(loaderstate *State, ctx context.Context, direct map[string]bool, rs *Requirements, add []module.Version) (*Requirements, error) { func updateUnprunedRoots(loaderstate *State, ctx context.Context, direct map[string]bool, rs *Requirements, add []module.Version) (*Requirements, error) {
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
// We can't ignore errors in the module graph even if the user passed the -e // We can't ignore errors in the module graph even if the user passed the -e
// flag to try to push past them. If we can't load the complete module // flag to try to push past them. If we can't load the complete module
@ -1487,7 +1488,7 @@ func convertPruning(loaderstate *State, ctx context.Context, rs *Requirements, p
// root set! “Include the transitive dependencies of every module in the build // root set! “Include the transitive dependencies of every module in the build
// list” is exactly what happens in a pruned module if we promote every module // list” is exactly what happens in a pruned module if we promote every module
// in the build list to a root. // in the build list to a root.
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return rs, err return rs, err
} }

View file

@ -7,6 +7,7 @@ package modload
import ( import (
"cmd/go/internal/cfg" "cmd/go/internal/cfg"
"cmd/go/internal/gover" "cmd/go/internal/gover"
"cmd/go/internal/modfetch"
"cmd/go/internal/mvs" "cmd/go/internal/mvs"
"cmd/internal/par" "cmd/internal/par"
"context" "context"
@ -100,7 +101,7 @@ func editRequirements(loaderstate *State, ctx context.Context, rs *Requirements,
// dependencies, so we need to treat everything in the build list as // dependencies, so we need to treat everything in the build list as
// potentially relevant — that is, as what would be a “root” in a module // potentially relevant — that is, as what would be a “root” in a module
// with graph pruning enabled. // with graph pruning enabled.
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
// If we couldn't load the graph, we don't know what its requirements were // If we couldn't load the graph, we don't know what its requirements were
// to begin with, so we can't edit those requirements in a coherent way. // to begin with, so we can't edit those requirements in a coherent way.
@ -391,7 +392,7 @@ func editRequirements(loaderstate *State, ctx context.Context, rs *Requirements,
// the edit. We want to make sure we consider keeping it as-is, // the edit. We want to make sure we consider keeping it as-is,
// even if it wouldn't normally be included. (For example, it might // even if it wouldn't normally be included. (For example, it might
// be a pseudo-version or pre-release.) // be a pseudo-version or pre-release.)
origMG, _ := orig.Graph(loaderstate, ctx) origMG, _ := orig.Graph(modfetch.Fetcher_, loaderstate, ctx)
origV := origMG.Selected(m.Path) origV := origMG.Selected(m.Path)
if conflict.Err != nil && origV == m.Version { if conflict.Err != nil && origV == m.Version {
@ -609,7 +610,7 @@ func editRequirements(loaderstate *State, ctx context.Context, rs *Requirements,
// some root to that version. // some root to that version.
func extendGraph(loaderstate *State, ctx context.Context, rootPruning modPruning, roots []module.Version, selectedRoot map[string]string) (mg *ModuleGraph, upgradedRoot map[module.Version]bool, err error) { func extendGraph(loaderstate *State, ctx context.Context, rootPruning modPruning, roots []module.Version, selectedRoot map[string]string) (mg *ModuleGraph, upgradedRoot map[module.Version]bool, err error) {
for { for {
mg, err = readModGraph(loaderstate, ctx, rootPruning, roots, upgradedRoot) mg, err = readModGraph(modfetch.Fetcher_, loaderstate, ctx, rootPruning, roots, upgradedRoot)
// We keep on going even if err is non-nil until we reach a steady state. // We keep on going even if err is non-nil until we reach a steady state.
// (Note that readModGraph returns a non-nil *ModuleGraph even in case of // (Note that readModGraph returns a non-nil *ModuleGraph even in case of
// errors.) The caller may be able to fix the errors by adjusting versions, // errors.) The caller may be able to fix the errors by adjusting versions,

View file

@ -481,7 +481,7 @@ func importFromModules(loaderstate *State, ctx context.Context, path string, rs
// of a package in "all", we didn't necessarily load that file // of a package in "all", we didn't necessarily load that file
// when we read the module graph, so do it now to be sure. // when we read the module graph, so do it now to be sure.
if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !loaderstate.MainModules.Contains(mods[0].Path) { if !skipModFile && cfg.BuildMod != "vendor" && mods[0].Path != "" && !loaderstate.MainModules.Contains(mods[0].Path) {
if _, err := goModSummary(loaderstate, mods[0]); err != nil { if _, err := goModSummary(modfetch.Fetcher_, loaderstate, mods[0]); err != nil {
return module.Version{}, "", "", nil, err return module.Version{}, "", "", nil, err
} }
} }
@ -506,7 +506,7 @@ func importFromModules(loaderstate *State, ctx context.Context, path string, rs
// So far we've checked the root dependencies. // So far we've checked the root dependencies.
// Load the full module graph and try again. // Load the full module graph and try again.
mg, err = rs.Graph(loaderstate, ctx) mg, err = rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
// We might be missing one or more transitive (implicit) dependencies from // We might be missing one or more transitive (implicit) dependencies from
// the module graph, so we can't return an ImportMissingError here — one // the module graph, so we can't return an ImportMissingError here — one
@ -543,7 +543,7 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
mv = module.ZeroPseudoVersion("v0") mv = module.ZeroPseudoVersion("v0")
} }
} }
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return module.Version{}, err return module.Version{}, err
} }
@ -637,7 +637,7 @@ func queryImport(loaderstate *State, ctx context.Context, path string, rs *Requi
// and return m, dir, ImportMissingError. // and return m, dir, ImportMissingError.
fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path) fmt.Fprintf(os.Stderr, "go: finding module for package %s\n", path)
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return module.Version{}, err return module.Version{}, err
} }
@ -817,7 +817,7 @@ func fetch(loaderstate *State, ctx context.Context, mod module.Version) (dir str
mod = r mod = r
} }
if mustHaveSums(loaderstate) && !modfetch.HaveSum(mod) { if mustHaveSums(loaderstate) && !modfetch.HaveSum(modfetch.Fetcher_, mod) {
return "", false, module.VersionError(mod, &sumMissingError{}) return "", false, module.VersionError(mod, &sumMissingError{})
} }

View file

@ -1965,7 +1965,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
if loaderstate.inWorkspaceMode() { if loaderstate.inWorkspaceMode() {
// go.mod files aren't updated in workspace mode, but we still want to // go.mod files aren't updated in workspace mode, but we still want to
// update the go.work.sum file. // update the go.work.sum file.
return modfetch.WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)) return modfetch.Fetcher_.WriteGoSum(ctx, keepSums(modfetch.Fetcher_, loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
} }
_, updatedGoMod, modFile, err := UpdateGoModFromReqs(loaderstate, ctx, opts) _, updatedGoMod, modFile, err := UpdateGoModFromReqs(loaderstate, ctx, opts)
if err != nil { if err != nil {
@ -1989,7 +1989,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
// Don't write go.mod, but write go.sum in case we added or trimmed sums. // Don't write go.mod, but write go.sum in case we added or trimmed sums.
// 'go mod init' shouldn't write go.sum, since it will be incomplete. // 'go mod init' shouldn't write go.sum, since it will be incomplete.
if cfg.CmdName != "mod init" { if cfg.CmdName != "mod init" {
if err := modfetch.WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)); err != nil { if err := modfetch.Fetcher_.WriteGoSum(ctx, keepSums(modfetch.Fetcher_, loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)); err != nil {
return err return err
} }
} }
@ -2012,7 +2012,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
// 'go mod init' shouldn't write go.sum, since it will be incomplete. // 'go mod init' shouldn't write go.sum, since it will be incomplete.
if cfg.CmdName != "mod init" { if cfg.CmdName != "mod init" {
if err == nil { if err == nil {
err = modfetch.WriteGoSum(ctx, keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate)) err = modfetch.Fetcher_.WriteGoSum(ctx, keepSums(modfetch.Fetcher_, loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums), mustHaveCompleteRequirements(loaderstate))
} }
} }
}() }()
@ -2055,7 +2055,7 @@ func commitRequirements(loaderstate *State, ctx context.Context, opts WriteOpts)
// including any go.mod files needed to reconstruct the MVS result // including any go.mod files needed to reconstruct the MVS result
// or identify go versions, // or identify go versions,
// in addition to the checksums for every module in keepMods. // in addition to the checksums for every module in keepMods.
func keepSums(loaderstate *State, ctx context.Context, ld *loader, rs *Requirements, which whichSums) map[module.Version]bool { func keepSums(fetcher_ *modfetch.Fetcher, loaderstate *State, ctx context.Context, ld *loader, rs *Requirements, which whichSums) map[module.Version]bool {
// Every module in the full module graph contributes its requirements, // Every module in the full module graph contributes its requirements,
// so in order to ensure that the build list itself is reproducible, // so in order to ensure that the build list itself is reproducible,
// we need sums for every go.mod in the graph (regardless of whether // we need sums for every go.mod in the graph (regardless of whether
@ -2113,7 +2113,7 @@ func keepSums(loaderstate *State, ctx context.Context, ld *loader, rs *Requireme
} }
} }
mg, _ := rs.Graph(loaderstate, ctx) mg, _ := rs.Graph(fetcher_, loaderstate, ctx)
for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) { for prefix := pkg.path; prefix != "."; prefix = path.Dir(prefix) {
if v := mg.Selected(prefix); v != "none" { if v := mg.Selected(prefix); v != "none" {
m := module.Version{Path: prefix, Version: v} m := module.Version{Path: prefix, Version: v}
@ -2136,7 +2136,7 @@ func keepSums(loaderstate *State, ctx context.Context, ld *loader, rs *Requireme
} }
} }
} else { } else {
mg, _ := rs.Graph(loaderstate, ctx) mg, _ := rs.Graph(fetcher_, loaderstate, ctx)
mg.WalkBreadthFirst(func(m module.Version) { mg.WalkBreadthFirst(func(m module.Version) {
if _, ok := mg.RequiredBy(m); ok { if _, ok := mg.RequiredBy(m); ok {
// The requirements from m's go.mod file are present in the module graph, // The requirements from m's go.mod file are present in the module graph,

View file

@ -311,7 +311,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
case strings.Contains(m.Pattern(), "..."): case strings.Contains(m.Pattern(), "..."):
m.Errs = m.Errs[:0] m.Errs = m.Errs[:0]
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
// The module graph is (or may be) incomplete — perhaps we failed to // The module graph is (or may be) incomplete — perhaps we failed to
// load the requirements of some module. This is an error in matching // load the requirements of some module. This is an error in matching
@ -404,7 +404,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
if opts.Tidy { if opts.Tidy {
if cfg.BuildV { if cfg.BuildV {
mg, _ := ld.requirements.Graph(loaderstate, ctx) mg, _ := ld.requirements.Graph(modfetch.Fetcher_, loaderstate, ctx)
for _, m := range initialRS.rootModules { for _, m := range initialRS.rootModules {
var unused bool var unused bool
if ld.requirements.pruning == unpruned { if ld.requirements.pruning == unpruned {
@ -425,7 +425,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
} }
} }
keep := keepSums(loaderstate, ctx, ld, ld.requirements, loadedZipSumsOnly) keep := keepSums(modfetch.Fetcher_, loaderstate, ctx, ld, ld.requirements, loadedZipSumsOnly)
compatVersion := ld.TidyCompatibleVersion compatVersion := ld.TidyCompatibleVersion
goVersion := ld.requirements.GoVersion(loaderstate) goVersion := ld.requirements.GoVersion(loaderstate)
if compatVersion == "" { if compatVersion == "" {
@ -447,7 +447,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
compatRS := newRequirements(loaderstate, compatPruning, ld.requirements.rootModules, ld.requirements.direct) compatRS := newRequirements(loaderstate, compatPruning, ld.requirements.rootModules, ld.requirements.direct)
ld.checkTidyCompatibility(loaderstate, ctx, compatRS, compatVersion) ld.checkTidyCompatibility(loaderstate, ctx, compatRS, compatVersion)
for m := range keepSums(loaderstate, ctx, ld, compatRS, loadedZipSumsOnly) { for m := range keepSums(modfetch.Fetcher_, loaderstate, ctx, ld, compatRS, loadedZipSumsOnly) {
keep[m] = true keep[m] = true
} }
} }
@ -466,7 +466,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
// Dropping compatibility for 1.16 may result in a strictly smaller go.sum. // Dropping compatibility for 1.16 may result in a strictly smaller go.sum.
// Update the keep map with only the loaded.requirements. // Update the keep map with only the loaded.requirements.
if gover.Compare(compatVersion, "1.16") > 0 { if gover.Compare(compatVersion, "1.16") > 0 {
keep = keepSums(loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums) keep = keepSums(modfetch.Fetcher_, loaderstate, ctx, loaded, loaderstate.requirements, addBuildListZipSums)
} }
currentGoSum, tidyGoSum := modfetch.TidyGoSum(keep) currentGoSum, tidyGoSum := modfetch.TidyGoSum(keep)
goSumDiff := diff.Diff("current/go.sum", currentGoSum, "tidy/go.sum", tidyGoSum) goSumDiff := diff.Diff("current/go.sum", currentGoSum, "tidy/go.sum", tidyGoSum)
@ -490,7 +490,7 @@ func LoadPackages(loaderstate *State, ctx context.Context, opts PackageOpts, pat
// loaded.requirements, but here we may have also loaded (and want to // loaded.requirements, but here we may have also loaded (and want to
// preserve checksums for) additional entities from compatRS, which are // preserve checksums for) additional entities from compatRS, which are
// only needed for compatibility with ld.TidyCompatibleVersion. // only needed for compatibility with ld.TidyCompatibleVersion.
if err := modfetch.WriteGoSum(ctx, keep, mustHaveCompleteRequirements(loaderstate)); err != nil { if err := modfetch.Fetcher_.WriteGoSum(ctx, keep, mustHaveCompleteRequirements(loaderstate)); err != nil {
base.Fatal(err) base.Fatal(err)
} }
} }
@ -747,7 +747,7 @@ func pathInModuleCache(loaderstate *State, ctx context.Context, dir string, rs *
// versions of root modules may differ from what we already checked above. // versions of root modules may differ from what we already checked above.
// Re-check those paths too. // Re-check those paths too.
mg, _ := rs.Graph(loaderstate, ctx) mg, _ := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
var importPath string var importPath string
for _, m := range mg.BuildList() { for _, m := range mg.BuildList() {
var found bool var found bool
@ -1253,7 +1253,7 @@ func loadFromRoots(loaderstate *State, ctx context.Context, params loaderParams)
// pruning and semantics all along, but there may have been — and may // pruning and semantics all along, but there may have been — and may
// still be — requirements on higher versions in the graph. // still be — requirements on higher versions in the graph.
tidy := overrideRoots(loaderstate, ctx, rs, []module.Version{{Path: "go", Version: ld.TidyGoVersion}}) tidy := overrideRoots(loaderstate, ctx, rs, []module.Version{{Path: "go", Version: ld.TidyGoVersion}})
mg, err := tidy.Graph(loaderstate, ctx) mg, err := tidy.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
ld.error(err) ld.error(err)
} }
@ -1412,7 +1412,7 @@ func (ld *loader) updateRequirements(loaderstate *State, ctx context.Context) (c
// of the vendor directory anyway. // of the vendor directory anyway.
continue continue
} }
if mg, err := rs.Graph(loaderstate, ctx); err != nil { if mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx); err != nil {
return false, err return false, err
} else if _, ok := mg.RequiredBy(dep.mod); !ok { } else if _, ok := mg.RequiredBy(dep.mod); !ok {
// dep.mod is not an explicit dependency, but needs to be. // dep.mod is not an explicit dependency, but needs to be.
@ -1515,7 +1515,7 @@ func (ld *loader) updateRequirements(loaderstate *State, ctx context.Context) (c
// The roots of the module graph have changed in some way (not just the // The roots of the module graph have changed in some way (not just the
// "direct" markings). Check whether the changes affected any of the loaded // "direct" markings). Check whether the changes affected any of the loaded
// packages. // packages.
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -1841,7 +1841,7 @@ func (ld *loader) load(loaderstate *State, ctx context.Context, pkg *loadPkg) {
var mg *ModuleGraph var mg *ModuleGraph
if ld.requirements.pruning == unpruned { if ld.requirements.pruning == unpruned {
var err error var err error
mg, err = ld.requirements.Graph(loaderstate, ctx) mg, err = ld.requirements.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
// We already checked the error from Graph in loadFromRoots and/or // We already checked the error from Graph in loadFromRoots and/or
// updateRequirements, so we ignored the error on purpose and we should // updateRequirements, so we ignored the error on purpose and we should
@ -2095,7 +2095,7 @@ func (ld *loader) checkTidyCompatibility(loaderstate *State, ctx context.Context
fmt.Fprintf(os.Stderr, "For information about 'go mod tidy' compatibility, see:\n\thttps://go.dev/ref/mod#graph-pruning\n") fmt.Fprintf(os.Stderr, "For information about 'go mod tidy' compatibility, see:\n\thttps://go.dev/ref/mod#graph-pruning\n")
} }
mg, err := rs.Graph(loaderstate, ctx) mg, err := rs.Graph(modfetch.Fetcher_, loaderstate, ctx)
if err != nil { if err != nil {
ld.error(fmt.Errorf("error loading go %s module graph: %w", compatVersion, err)) ld.error(fmt.Errorf("error loading go %s module graph: %w", compatVersion, err))
ld.switchIfErrors(ctx) ld.switchIfErrors(ctx)

View file

@ -214,7 +214,7 @@ func (s *State) CheckRetractions(ctx context.Context, m module.Version) (err err
if err != nil { if err != nil {
return err return err
} }
summary, err := rawGoModSummary(s, rm) summary, err := rawGoModSummary(modfetch.Fetcher_, s, rm)
if err != nil && !errors.Is(err, gover.ErrTooNew) { if err != nil && !errors.Is(err, gover.ErrTooNew) {
return err return err
} }
@ -322,7 +322,7 @@ func CheckDeprecation(loaderstate *State, ctx context.Context, m module.Version)
if err != nil { if err != nil {
return "", err return "", err
} }
summary, err := rawGoModSummary(loaderstate, latest) summary, err := rawGoModSummary(modfetch.Fetcher_, loaderstate, latest)
if err != nil && !errors.Is(err, gover.ErrTooNew) { if err != nil && !errors.Is(err, gover.ErrTooNew) {
return "", err return "", err
} }
@ -573,12 +573,12 @@ type retraction struct {
// module versions. // module versions.
// //
// The caller must not modify the returned summary. // The caller must not modify the returned summary.
func goModSummary(loaderstate *State, m module.Version) (*modFileSummary, error) { func goModSummary(fetcher_ *modfetch.Fetcher, loaderstate *State, m module.Version) (*modFileSummary, error) {
if m.Version == "" && !loaderstate.inWorkspaceMode() && loaderstate.MainModules.Contains(m.Path) { if m.Version == "" && !loaderstate.inWorkspaceMode() && loaderstate.MainModules.Contains(m.Path) {
panic("internal error: goModSummary called on a main module") panic("internal error: goModSummary called on a main module")
} }
if gover.IsToolchain(m.Path) { if gover.IsToolchain(m.Path) {
return rawGoModSummary(loaderstate, m) return rawGoModSummary(fetcher_, loaderstate, m)
} }
if cfg.BuildMod == "vendor" { if cfg.BuildMod == "vendor" {
@ -604,12 +604,12 @@ func goModSummary(loaderstate *State, m module.Version) (*modFileSummary, error)
actual := resolveReplacement(loaderstate, m) actual := resolveReplacement(loaderstate, m)
if mustHaveSums(loaderstate) && actual.Version != "" { if mustHaveSums(loaderstate) && actual.Version != "" {
key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"} key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
if !modfetch.HaveSum(key) { if !modfetch.HaveSum(fetcher_, key) {
suggestion := fmt.Sprintf(" for go.mod file; to add it:\n\tgo mod download %s", m.Path) suggestion := fmt.Sprintf(" for go.mod file; to add it:\n\tgo mod download %s", m.Path)
return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion}) return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion})
} }
} }
summary, err := rawGoModSummary(loaderstate, actual) summary, err := rawGoModSummary(fetcher_, loaderstate, actual)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -676,7 +676,7 @@ func goModSummary(loaderstate *State, m module.Version) (*modFileSummary, error)
// rawGoModSummary cannot be used on the main module outside of workspace mode. // rawGoModSummary cannot be used on the main module outside of workspace mode.
// The modFileSummary can still be used for retractions and deprecations // The modFileSummary can still be used for retractions and deprecations
// even if a TooNewError is returned. // even if a TooNewError is returned.
func rawGoModSummary(loaderstate *State, m module.Version) (*modFileSummary, error) { func rawGoModSummary(fetcher_ *modfetch.Fetcher, loaderstate *State, m module.Version) (*modFileSummary, error) {
if gover.IsToolchain(m.Path) { if gover.IsToolchain(m.Path) {
if m.Path == "go" && gover.Compare(m.Version, gover.GoStrictVersion) >= 0 { if m.Path == "go" && gover.Compare(m.Version, gover.GoStrictVersion) >= 0 {
// Declare that go 1.21.3 requires toolchain 1.21.3, // Declare that go 1.21.3 requires toolchain 1.21.3,
@ -709,7 +709,7 @@ func rawGoModSummary(loaderstate *State, m module.Version) (*modFileSummary, err
} }
} }
return rawGoModSummaryCache.Do(m, func() (*modFileSummary, error) { return rawGoModSummaryCache.Do(m, func() (*modFileSummary, error) {
name, data, err := rawGoModData(loaderstate, m) name, data, err := rawGoModData(fetcher_, loaderstate, m)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -781,7 +781,7 @@ var rawGoModSummaryCache par.ErrCache[module.Version, *modFileSummary]
// //
// Unlike rawGoModSummary, rawGoModData does not cache its results in memory. // Unlike rawGoModSummary, rawGoModData does not cache its results in memory.
// Use rawGoModSummary instead unless you specifically need these bytes. // Use rawGoModSummary instead unless you specifically need these bytes.
func rawGoModData(loaderstate *State, m module.Version) (name string, data []byte, err error) { func rawGoModData(fetcher_ *modfetch.Fetcher, loaderstate *State, m module.Version) (name string, data []byte, err error) {
if m.Version == "" { if m.Version == "" {
dir := m.Path dir := m.Path
if !filepath.IsAbs(dir) { if !filepath.IsAbs(dir) {
@ -810,7 +810,7 @@ func rawGoModData(loaderstate *State, m module.Version) (name string, data []byt
base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version) base.Fatalf("go: internal error: %s@%s: unexpected invalid semantic version", m.Path, m.Version)
} }
name = "go.mod" name = "go.mod"
data, err = modfetch.GoMod(context.TODO(), m.Path, m.Version) data, err = fetcher_.GoMod(context.TODO(), m.Path, m.Version)
} }
return name, data, err return name, data, err
} }

View file

@ -54,7 +54,7 @@ func (r *mvsReqs) Required(mod module.Version) ([]module.Version, error) {
return nil, nil return nil, nil
} }
summary, err := goModSummary(r.loaderstate, mod) summary, err := goModSummary(modfetch.Fetcher_, r.loaderstate, mod)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -1099,7 +1099,7 @@ func (e *PackageNotInModuleError) ImportPath() string {
// we don't need to verify it in go.sum. This makes 'go list -m -u' faster // we don't need to verify it in go.sum. This makes 'go list -m -u' faster
// and simpler. // and simpler.
func versionHasGoMod(loaderstate *State, _ context.Context, m module.Version) (bool, error) { func versionHasGoMod(loaderstate *State, _ context.Context, m module.Version) (bool, error) {
_, data, err := rawGoModData(loaderstate, m) _, data, err := rawGoModData(modfetch.Fetcher_, loaderstate, m)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -1124,7 +1124,7 @@ func lookupRepo(loaderstate *State, ctx context.Context, proxy, path string) (re
err = module.CheckPath(path) err = module.CheckPath(path)
} }
if err == nil { if err == nil {
repo = modfetch.Lookup(ctx, proxy, path) repo = modfetch.Fetcher_.Lookup(ctx, proxy, path)
} else { } else {
repo = emptyRepo{path: path, err: err} repo = emptyRepo{path: path, err: err}
} }

View file

@ -21,6 +21,7 @@ import (
"cmd/go/internal/fsys" "cmd/go/internal/fsys"
"cmd/go/internal/gover" "cmd/go/internal/gover"
"cmd/go/internal/imports" "cmd/go/internal/imports"
"cmd/go/internal/modfetch"
"cmd/go/internal/modindex" "cmd/go/internal/modindex"
"cmd/go/internal/search" "cmd/go/internal/search"
"cmd/go/internal/str" "cmd/go/internal/str"
@ -348,7 +349,7 @@ func parseIgnorePatterns(loaderstate *State, ctx context.Context, treeCanMatch f
if err != nil { if err != nil {
continue continue
} }
summary, err := goModSummary(loaderstate, mod) summary, err := goModSummary(modfetch.Fetcher_, loaderstate, mod)
if err != nil { if err != nil {
continue continue
} }

View file

@ -146,7 +146,7 @@ func NewerToolchain(ctx context.Context, version string) (string, error) {
func autoToolchains(ctx context.Context) ([]string, error) { func autoToolchains(ctx context.Context) ([]string, error) {
var versions *modfetch.Versions var versions *modfetch.Versions
err := modfetch.TryProxies(func(proxy string) error { err := modfetch.TryProxies(func(proxy string) error {
v, err := modfetch.Lookup(ctx, proxy, "go").Versions(ctx, "") v, err := modfetch.Fetcher_.Lookup(ctx, proxy, "go").Versions(ctx, "")
if err != nil { if err != nil {
return err return err
} }