From 07b10e97d6552e16534aae51f140771a601ef385 Mon Sep 17 00:00:00 2001 From: Ian Alexander Date: Mon, 24 Nov 2025 16:53:11 -0500 Subject: [PATCH] cmd/go/internal/modcmd: inject modfetch.Fetcher_ into DownloadModule 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/modcmd rf ' inject modfetch.Fetcher_ DownloadModule ' cd ../modfetch rf ' add downloadZip:/f, err := tempFile.*/+0 _ = f \ file, err := tempFile(ctx, filepath.Dir(zipfile), filepath.Base(zipfile), 0o666) \ _ = file ' rf ' add downloadZip:/f.Close\(\)/+0 file.Close() rm downloadZip:/file.Close\(\)/-1 add downloadZip:/os.Remove\(f.Name\(\)\)/+0 os.Remove(file.Name()) rm downloadZip:/os.Remove\(file.Name\(\)\)/-1 ' sed -i ' s/ f, err := tempFile(ctx, filepath.Dir(zipfile), filepath.Base(zipfile), 0o666)/file, err := tempFile(ctx, filepath.Dir(zipfile), filepath.Base(zipfile), 0o666)/ s/err := repo.Zip(ctx, f, mod.Version)/err := repo.Zip(ctx, file, mod.Version)/ s/if _, err := f.Seek(0, io.SeekStart); err != nil {/if _, err := file.Seek(0, io.SeekStart); err != nil {/ s/if err := f.Truncate(0); err != nil {/if err := file.Truncate(0); err != nil {/ s/fi, err := f.Stat()/fi, err := file.Stat()/ s/z, err := zip.NewReader(f, fi.Size())/z, err := zip.NewReader(file, fi.Size())/ s/for _, f := range z.File {/for _, zf := range z.File {/ s/if !strings.HasPrefix(f.Name, prefix) {/if !strings.HasPrefix(zf.Name, prefix) {/ s/return fmt.Errorf("zip for %s has unexpected file %s", prefix\[:len(prefix)-1\], f.Name)/return fmt.Errorf("zip for %s has unexpected file %s", prefix[:len(prefix)-1], zf.Name)/ s/if err := f.Close(); err != nil {/if err := file.Close(); err != nil {/ s/if err := hashZip(fetcher_, mod, f.Name(), ziphashfile); err != nil {/if err := hashZip(fetcher_, mod, file.Name(), ziphashfile); err != nil {/ s/if err := os.Rename(f.Name(), zipfile); err != nil {/if err := os.Rename(file.Name(), zipfile); err != nil {/ ' fetch.go rf ' rm downloadZip:/_ = file/-3 downloadZip:/_ = file/-2 downloadZip:/file, err := tempFile\(ctx, filepath.Dir\(zipfile\), filepath.Base\(zipfile\), 0o666\)/+1 ' rf ' mv InfoFile.fetcher_ InfoFile.f mv InfoFile Fetcher.InfoFile mv GoModFile.fetcher_ GoModFile.f mv GoModFile Fetcher.GoModFile mv GoModSum.fetcher_ GoModSum.f mv GoModSum Fetcher.GoModSum mv Download.fetcher_ Download.f mv Download Fetcher.Download mv download.fetcher_ download.f mv download Fetcher.download mv DownloadZip.fetcher_ DownloadZip.f mv DownloadZip Fetcher.DownloadZip mv downloadZip.fetcher_ downloadZip.f mv downloadZip Fetcher.downloadZip mv checkMod.fetcher_ checkMod.f mv checkMod Fetcher.checkMod mv hashZip.fetcher_ hashZip.f ' Change-Id: I1d2e09b8523f5ef2be04b91d858d98fb79c0a771 Reviewed-on: https://go-review.googlesource.com/c/go/+/724242 LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Matloob Reviewed-by: Michael Matloob --- src/cmd/go/internal/modcmd/download.go | 10 +-- src/cmd/go/internal/modfetch/cache.go | 12 ++-- src/cmd/go/internal/modfetch/fetch.go | 64 +++++++++---------- .../modfetch/zip_sum_test/zip_sum_test.go | 2 +- src/cmd/go/internal/modget/get.go | 2 +- src/cmd/go/internal/modload/import.go | 2 +- src/cmd/go/internal/toolchain/select.go | 2 +- 7 files changed, 47 insertions(+), 47 deletions(-) diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go index 150d0c8860..8b94ba1fd5 100644 --- a/src/cmd/go/internal/modcmd/download.go +++ b/src/cmd/go/internal/modcmd/download.go @@ -366,25 +366,25 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { // leaving the results (including any error) in m itself. func DownloadModule(ctx context.Context, m *ModuleJSON) error { var err error - _, file, err := modfetch.InfoFile(ctx, m.Path, m.Version) + _, file, err := modfetch.Fetcher_.InfoFile(ctx, m.Path, m.Version) if err != nil { return err } m.Info = file - m.GoMod, err = modfetch.GoModFile(ctx, m.Path, m.Version) + m.GoMod, err = modfetch.Fetcher_.GoModFile(ctx, m.Path, m.Version) if err != nil { return err } - m.GoModSum, err = modfetch.GoModSum(ctx, m.Path, m.Version) + m.GoModSum, err = modfetch.Fetcher_.GoModSum(ctx, m.Path, m.Version) if err != nil { return err } mod := module.Version{Path: m.Path, Version: m.Version} - m.Zip, err = modfetch.DownloadZip(ctx, mod) + m.Zip, err = modfetch.Fetcher_.DownloadZip(ctx, mod) if err != nil { return err } m.Sum = modfetch.Sum(ctx, mod) - m.Dir, err = modfetch.Download(ctx, mod) + m.Dir, err = modfetch.Fetcher_.Download(ctx, mod) return err } diff --git a/src/cmd/go/internal/modfetch/cache.go b/src/cmd/go/internal/modfetch/cache.go index b0bb7a878a..3886d3b1fe 100644 --- a/src/cmd/go/internal/modfetch/cache.go +++ b/src/cmd/go/internal/modfetch/cache.go @@ -341,7 +341,7 @@ func (r *cachingRepo) Zip(ctx context.Context, dst io.Writer, version string) er // InfoFile is like Lookup(ctx, path).Stat(version) but also returns the name of the file // containing the cached information. -func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, error) { +func (f *Fetcher) InfoFile(ctx context.Context, path, version string) (*RevInfo, string, error) { if !gover.ModIsValid(path, version) { return nil, "", fmt.Errorf("invalid version %q", version) } @@ -353,7 +353,7 @@ func InfoFile(ctx context.Context, path, version string) (*RevInfo, string, erro var info *RevInfo var err2info map[error]*RevInfo err := TryProxies(func(proxy string) error { - i, err := Fetcher_.Lookup(ctx, proxy, path).Stat(ctx, version) + i, err := f.Lookup(ctx, proxy, path).Stat(ctx, version) if err == nil { info = i } else { @@ -416,11 +416,11 @@ func (f *Fetcher) GoMod(ctx context.Context, path, rev string) ([]byte, error) { // GoModFile is like GoMod but returns the name of the file containing // the cached information. -func GoModFile(ctx context.Context, path, version string) (string, error) { +func (f *Fetcher) GoModFile(ctx context.Context, path, version string) (string, error) { if !gover.ModIsValid(path, version) { return "", fmt.Errorf("invalid version %q", version) } - if _, err := Fetcher_.GoMod(ctx, path, version); err != nil { + if _, err := f.GoMod(ctx, path, version); err != nil { return "", err } // GoMod should have populated the disk cache for us. @@ -433,11 +433,11 @@ func GoModFile(ctx context.Context, path, version string) (string, error) { // GoModSum returns the go.sum entry for the module version's go.mod file. // (That is, it returns the entry listed in go.sum as "path version/go.mod".) -func GoModSum(ctx context.Context, path, version string) (string, error) { +func (f *Fetcher) GoModSum(ctx context.Context, path, version string) (string, error) { if !gover.ModIsValid(path, version) { return "", fmt.Errorf("invalid version %q", version) } - data, err := Fetcher_.GoMod(ctx, path, version) + data, err := f.GoMod(ctx, path, version) if err != nil { return "", err } diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go index 6cddc5b7fb..87f6915625 100644 --- a/src/cmd/go/internal/modfetch/fetch.go +++ b/src/cmd/go/internal/modfetch/fetch.go @@ -40,7 +40,7 @@ var ErrToolchain = errors.New("internal error: invalid operation on toolchain mo // Download downloads the specific module version to the // local download cache and returns the name of the directory // corresponding to the root of the module's file tree. -func Download(ctx context.Context, mod module.Version) (dir string, err error) { +func (f *Fetcher) Download(ctx context.Context, mod module.Version) (dir string, err error) { if gover.IsToolchain(mod.Path) { return "", ErrToolchain } @@ -49,12 +49,12 @@ func Download(ctx context.Context, mod module.Version) (dir string, err error) { } // The par.Cache here avoids duplicate work. - return Fetcher_.downloadCache.Do(mod, func() (string, error) { - dir, err := download(ctx, mod) + return f.downloadCache.Do(mod, func() (string, error) { + dir, err := f.download(ctx, mod) if err != nil { return "", err } - checkMod(ctx, mod) + f.checkMod(ctx, mod) // If go.mod exists (not an old legacy module), check version is not too new. if data, err := os.ReadFile(filepath.Join(dir, "go.mod")); err == nil { @@ -94,7 +94,7 @@ func (f *Fetcher) Unzip(ctx context.Context, mod module.Version, zipfile string) }) } -func download(ctx context.Context, mod module.Version) (dir string, err error) { +func (f *Fetcher) download(ctx context.Context, mod module.Version) (dir string, err error) { ctx, span := trace.StartSpan(ctx, "modfetch.download "+mod.String()) defer span.Done() @@ -109,7 +109,7 @@ func download(ctx context.Context, mod module.Version) (dir string, err error) { // To avoid cluttering the cache with extraneous files, // DownloadZip uses the same lockfile as Download. // Invoke DownloadZip before locking the file. - zipfile, err := DownloadZip(ctx, mod) + zipfile, err := f.DownloadZip(ctx, mod) if err != nil { return "", err } @@ -198,7 +198,7 @@ var downloadZipCache par.ErrCache[module.Version, string] // DownloadZip downloads the specific module version to the // local zip cache and returns the name of the zip file. -func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error) { +func (f *Fetcher) DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error) { // The par.Cache here avoids duplicate work. return downloadZipCache.Do(mod, func() (string, error) { zipfile, err := CachePath(ctx, mod, "zip") @@ -210,8 +210,8 @@ func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err e // Return early if the zip and ziphash files exist. if _, err := os.Stat(zipfile); err == nil { if _, err := os.Stat(ziphashfile); err == nil { - if !HaveSum(Fetcher_, mod) { - checkMod(ctx, mod) + if !HaveSum(f, mod) { + f.checkMod(ctx, mod) } return zipfile, nil } @@ -238,14 +238,14 @@ func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err e } defer unlock() - if err := downloadZip(ctx, mod, zipfile); err != nil { + if err := f.downloadZip(ctx, mod, zipfile); err != nil { return "", err } return zipfile, nil }) } -func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error) { +func (f *Fetcher) downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error) { ctx, span := trace.StartSpan(ctx, "modfetch.downloadZip "+zipfile) defer span.Done() @@ -281,7 +281,7 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e // If the zip file exists, the ziphash file must have been deleted // or lost after a file system crash. Re-hash the zip without downloading. if zipExists { - return hashZip(mod, zipfile, ziphashfile) + return hashZip(f, mod, zipfile, ziphashfile) } // From here to the os.Rename call below is functionally almost equivalent to @@ -289,14 +289,14 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e // contents of the file (by hashing it) before we commit it. Because the file // is zip-compressed, we need an actual file — or at least an io.ReaderAt — to // validate it: we can't just tee the stream as we write it. - f, err := tempFile(ctx, filepath.Dir(zipfile), filepath.Base(zipfile), 0o666) + file, err := tempFile(ctx, filepath.Dir(zipfile), filepath.Base(zipfile), 0o666) if err != nil { return err } defer func() { if err != nil { - f.Close() - os.Remove(f.Name()) + file.Close() + os.Remove(file.Name()) } }() @@ -305,18 +305,18 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e if unrecoverableErr != nil { return unrecoverableErr } - repo := Fetcher_.Lookup(ctx, proxy, mod.Path) - err := repo.Zip(ctx, f, mod.Version) + repo := f.Lookup(ctx, proxy, mod.Path) + err := repo.Zip(ctx, file, mod.Version) if err != nil { // Zip may have partially written to f before failing. // (Perhaps the server crashed while sending the file?) // Since we allow fallback on error in some cases, we need to fix up the // file to be empty again for the next attempt. - if _, err := f.Seek(0, io.SeekStart); err != nil { + if _, err := file.Seek(0, io.SeekStart); err != nil { unrecoverableErr = err return err } - if err := f.Truncate(0); err != nil { + if err := file.Truncate(0); err != nil { unrecoverableErr = err return err } @@ -330,30 +330,30 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e // Double-check that the paths within the zip file are well-formed. // // TODO(bcmills): There is a similar check within the Unzip function. Can we eliminate one? - fi, err := f.Stat() + fi, err := file.Stat() if err != nil { return err } - z, err := zip.NewReader(f, fi.Size()) + z, err := zip.NewReader(file, fi.Size()) if err != nil { return err } prefix := mod.Path + "@" + mod.Version + "/" - for _, f := range z.File { - if !strings.HasPrefix(f.Name, prefix) { - return fmt.Errorf("zip for %s has unexpected file %s", prefix[:len(prefix)-1], f.Name) + for _, zf := range z.File { + if !strings.HasPrefix(zf.Name, prefix) { + return fmt.Errorf("zip for %s has unexpected file %s", prefix[:len(prefix)-1], zf.Name) } } - if err := f.Close(); err != nil { + if err := file.Close(); err != nil { return err } // Hash the zip file and check the sum before renaming to the final location. - if err := hashZip(mod, f.Name(), ziphashfile); err != nil { + if err := hashZip(f, mod, file.Name(), ziphashfile); err != nil { return err } - if err := os.Rename(f.Name(), zipfile); err != nil { + if err := os.Rename(file.Name(), zipfile); err != nil { return err } @@ -367,12 +367,12 @@ func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err e // // If the hash does not match go.sum (or the sumdb if enabled), hashZip returns // an error and does not write ziphashfile. -func hashZip(mod module.Version, zipfile, ziphashfile string) (err error) { +func hashZip(f *Fetcher, mod module.Version, zipfile, ziphashfile string) (err error) { hash, err := dirhash.HashZip(zipfile, dirhash.DefaultHash) if err != nil { return err } - if err := checkModSum(Fetcher_, mod, hash); err != nil { + if err := checkModSum(f, mod, hash); err != nil { return err } hf, err := lockedfile.Create(ziphashfile) @@ -702,7 +702,7 @@ func RecordedSum(mod module.Version) (sum string, ok bool) { } // checkMod checks the given module's checksum and Go version. -func checkMod(ctx context.Context, mod module.Version) { +func (f *Fetcher) checkMod(ctx context.Context, mod module.Version) { // Do the file I/O before acquiring the go.sum lock. ziphash, err := CachePath(ctx, mod, "ziphash") if err != nil { @@ -719,7 +719,7 @@ func checkMod(ctx context.Context, mod module.Version) { if err != nil { base.Fatalf("verifying %v", module.VersionError(mod, err)) } - err = hashZip(mod, zip, ziphash) + err = hashZip(f, mod, zip, ziphash) if err != nil { base.Fatalf("verifying %v", module.VersionError(mod, err)) } @@ -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))) } - if err := checkModSum(Fetcher_, mod, h); err != nil { + if err := checkModSum(f, mod, h); err != nil { base.Fatalf("%s", err) } } diff --git a/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go b/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go index edae1d8f3c..6d11dbc5bf 100644 --- a/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go +++ b/src/cmd/go/internal/modfetch/zip_sum_test/zip_sum_test.go @@ -119,7 +119,7 @@ func TestZipSums(t *testing.T) { t.Parallel() ctx := context.Background() - zipPath, err := modfetch.DownloadZip(ctx, test.m) + zipPath, err := modfetch.Fetcher_.DownloadZip(ctx, test.m) if err != nil { if *updateTestData { t.Logf("%s: could not download module: %s (will remove from testdata)", test.m, err) diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go index 839bee103f..d2458eba9b 100644 --- a/src/cmd/go/internal/modget/get.go +++ b/src/cmd/go/internal/modget/get.go @@ -1792,7 +1792,7 @@ func (r *resolver) checkPackageProblems(loaderstate *modload.State, ctx context. continue } r.work.Add(func() { - if _, err := modfetch.DownloadZip(ctx, mActual); err != nil { + if _, err := modfetch.Fetcher_.DownloadZip(ctx, mActual); err != nil { verb := "upgraded" if gover.ModCompare(m.Path, m.Version, old.Version) < 0 { verb = "downgraded" diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go index b7147f948d..eb97d5ff78 100644 --- a/src/cmd/go/internal/modload/import.go +++ b/src/cmd/go/internal/modload/import.go @@ -821,7 +821,7 @@ func fetch(loaderstate *State, ctx context.Context, mod module.Version) (dir str return "", false, module.VersionError(mod, &sumMissingError{}) } - dir, err = modfetch.Download(ctx, mod) + dir, err = modfetch.Fetcher_.Download(ctx, mod) return dir, false, err } diff --git a/src/cmd/go/internal/toolchain/select.go b/src/cmd/go/internal/toolchain/select.go index 4c7e7a5e57..c27bcb5bbd 100644 --- a/src/cmd/go/internal/toolchain/select.go +++ b/src/cmd/go/internal/toolchain/select.go @@ -360,7 +360,7 @@ func Exec(s *modload.State, gotoolchain string) { Path: gotoolchainModule, Version: gotoolchainVersion + "-" + gotoolchain + "." + runtime.GOOS + "-" + runtime.GOARCH, } - dir, err := modfetch.Download(context.Background(), m) + dir, err := modfetch.Fetcher_.Download(context.Background(), m) if err != nil { if errors.Is(err, fs.ErrNotExist) { toolVers := gover.FromToolchain(gotoolchain) -- 2.52.0