internal/fetch: ModuleGetter.FS returns the content dir
Move the responsibility for getting the module zip's content directory
from FetchModule to the ModuleGetters.
This will enable a ModuleGetter that reads directly from the on-disk
filesystem.
For golang/go#47834
Change-Id: I035a88680569272845ad12deb09ed94e6a37bf66
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/343961
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/internal/fetch/fetch.go b/internal/fetch/fetch.go
index 563ba5b..5eeae8f 100644
--- a/internal/fetch/fetch.go
+++ b/internal/fetch/fetch.go
@@ -185,7 +185,7 @@
}
startFetchInfo(fi)
- var fsys fs.FS
+ var contentDir fs.FS
if fr.ModulePath == stdlib.ModulePath {
var (
resolvedVersion string
@@ -195,31 +195,25 @@
if err != nil {
return fi, err
}
- fsys = zr
+ v := resolvedVersion
+ if stdlib.SupportedBranches[fr.RequestedVersion] {
+ v = fr.RequestedVersion
+ }
+ contentDir, err = fs.Sub(zr, fr.ModulePath+"@"+v)
+ if err != nil {
+ return fi, err
+ }
// If the requested version is a branch name like "master" or "main", we cannot
// determine the right resolved version until we start working with the repo.
fr.ResolvedVersion = resolvedVersion
fi.Version = resolvedVersion
} else {
- fsys, err = mg.FS(ctx, fr.ModulePath, fr.ResolvedVersion)
+ contentDir, err = mg.FS(ctx, fr.ModulePath, fr.ResolvedVersion)
if err != nil {
return fi, err
}
}
- // Use the content directory of the module filesystem throughout. That is
- // the "<module>@<resolvedVersion>" directory that all module zips are
- // expected to have according to the zip archive layout specification at
- // https://golang.org/ref/mod#zip-files.
- v := fr.ResolvedVersion
- if fr.ModulePath == stdlib.ModulePath && stdlib.SupportedBranches[fr.RequestedVersion] {
- v = fr.RequestedVersion
- }
- contentDir, err := fs.Sub(fsys, fr.ModulePath+"@"+v)
- if err != nil {
- return fi, err
- }
-
// Set fr.HasGoMod as early as possible, because the go command uses it to
// decide the latest version in some cases (see fetchRawLatestVersion in
// this package) and all it requires is a valid zip.
diff --git a/internal/fetch/fs_test.go b/internal/fetch/fs_test.go
index 060103f..3290015 100644
--- a/internal/fetch/fs_test.go
+++ b/internal/fetch/fs_test.go
@@ -6,7 +6,6 @@
import (
"context"
- "fmt"
"io/ioutil"
"testing"
"time"
@@ -78,7 +77,7 @@
t.Fatal(err)
}
// Just check that the go.mod file is there and has the right contents.
- f, err := fsys.Open(fmt.Sprintf("%s@%s/go.mod", modulePath, version))
+ f, err := fsys.Open("go.mod")
if err != nil {
t.Fatal(err)
}
diff --git a/internal/fetch/getters.go b/internal/fetch/getters.go
index 89591cd..f2b9a07 100644
--- a/internal/fetch/getters.go
+++ b/internal/fetch/getters.go
@@ -31,11 +31,17 @@
type ModuleGetter interface {
// Info returns basic information about the module.
Info(ctx context.Context, path, version string) (*proxy.VersionInfo, error)
+
// Mod returns the contents of the module's go.mod file.
Mod(ctx context.Context, path, version string) ([]byte, error)
- // FS returns an FS for the module's contents. The FS should match the format
- // of a module zip file.
+
+ // FS returns an FS for the module's contents. The FS should match the
+ // format of a module zip file's content directory. That is the
+ // "<module>@<resolvedVersion>" directory that all module zips are expected
+ // to have according to the zip archive layout specification at
+ // https://golang.org/ref/mod#zip-files.
FS(ctx context.Context, path, version string) (fs.FS, error)
+
// ZipSize returns the approximate size of the zip file in bytes.
// It is used only for load-shedding.
ZipSize(ctx context.Context, path, version string) (int64, error)
@@ -62,7 +68,11 @@
// FS returns an FS for the module's contents. The FS should match the format
// of a module zip file.
func (g *proxyModuleGetter) FS(ctx context.Context, path, version string) (fs.FS, error) {
- return g.prox.Zip(ctx, path, version)
+ zr, err := g.prox.Zip(ctx, path, version)
+ if err != nil {
+ return nil, err
+ }
+ return fs.Sub(zr, path+"@"+version)
}
// ZipSize returns the approximate size of the zip file in bytes.
@@ -140,7 +150,11 @@
if err := g.checkPath(path); err != nil {
return nil, err
}
- return createZipReader(g.dir, path, LocalVersion)
+ zr, err := createZipReader(g.dir, path, LocalVersion)
+ if err != nil {
+ return nil, err
+ }
+ return fs.Sub(zr, path+"@"+LocalVersion)
}
// ZipSize returns the approximate size of the zip file in bytes.
@@ -231,7 +245,11 @@
if err != nil {
return nil, err
}
- return zip.NewReader(bytes.NewReader(data), int64(len(data)))
+ zr, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
+ if err != nil {
+ return nil, err
+ }
+ return fs.Sub(zr, path+"@"+version)
}
// ZipSize returns the approximate size of the zip file in bytes.