cmd/pkgsite: support the module cache
With the -cache flag, fetch modules from the module cache.
For golang/go#47780
Change-Id: I2aa6467955cd90a80ccae559f27928cca6e06079
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/345272
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/cmd/pkgsite/main.go b/cmd/pkgsite/main.go
index 31f1102..61ef2c7 100644
--- a/cmd/pkgsite/main.go
+++ b/cmd/pkgsite/main.go
@@ -26,6 +26,8 @@
"fmt"
"net/http"
"os"
+ "os/exec"
+ "path/filepath"
"strings"
"time"
@@ -47,6 +49,8 @@
_ = flag.String("static", "static", "path to folder containing static files served")
gopathMode = flag.Bool("gopath_mode", false, "assume that local modules' paths are relative to GOPATH/src")
httpAddr = flag.String("http", defaultAddr, "HTTP service address to listen for incoming requests on")
+ useCache = flag.Bool("cache", false, "fetch from the module cache")
+ cacheDir = flag.String("cachedir", "", "module cache directory (defaults to `go env GOMODCACHE`)")
useProxy = flag.Bool("proxy", false, "fetch from GOPROXY if not found locally")
)
@@ -64,6 +68,23 @@
paths = []string{"."}
}
+ var downloadDir string
+ if *useCache {
+ downloadDir = *cacheDir
+ if downloadDir == "" {
+ var err error
+ downloadDir, err = defaultCacheDir()
+ if err != nil {
+ die("%v", err)
+ }
+ if downloadDir == "" {
+ die("empty value for GOMODCACHE")
+ }
+ }
+ // We actually serve from the download subdirectory.
+ downloadDir = filepath.Join(downloadDir, "cache", "download")
+ }
+
var prox *proxy.Client
if *useProxy {
fmt.Fprintf(os.Stderr, "BYPASSING LICENSE CHECKING: MAY DISPLAY NON-REDISTRIBUTABLE INFORMATION\n")
@@ -77,7 +98,7 @@
die("connecting to proxy: %s", err)
}
}
- server, err := newServer(ctx, paths, *gopathMode, prox)
+ server, err := newServer(ctx, paths, *gopathMode, downloadDir, prox)
if err != nil {
die("%s", err)
}
@@ -101,8 +122,11 @@
return paths
}
-func newServer(ctx context.Context, paths []string, gopathMode bool, prox *proxy.Client) (*frontend.Server, error) {
+func newServer(ctx context.Context, paths []string, gopathMode bool, downloadDir string, prox *proxy.Client) (*frontend.Server, error) {
getters := buildGetters(ctx, paths, gopathMode)
+ if downloadDir != "" {
+ getters = append(getters, fetch.NewFSProxyModuleGetter(downloadDir))
+ }
if prox != nil {
getters = append(getters, fetch.NewProxyModuleGetter(prox))
}
@@ -148,3 +172,11 @@
}
return getters
}
+
+func defaultCacheDir() (string, error) {
+ out, err := exec.Command("go", "env", "GOMODCACHE").CombinedOutput()
+ if err != nil {
+ return "", fmt.Errorf("running 'go env GOMODCACHE': %v: %s", err, out)
+ }
+ return strings.TrimSpace(string(out)), nil
+}
diff --git a/cmd/pkgsite/main_test.go b/cmd/pkgsite/main_test.go
index 3a90036..ce0356f 100644
--- a/cmd/pkgsite/main_test.go
+++ b/cmd/pkgsite/main_test.go
@@ -10,6 +10,7 @@
"net/http"
"net/http/httptest"
"path/filepath"
+ "strings"
"testing"
"github.com/google/go-cmp/cmp"
@@ -18,25 +19,41 @@
func Test(t *testing.T) {
repoPath := func(fn string) string { return filepath.Join("..", "..", fn) }
+
localModule := repoPath("internal/fetch/testdata/has_go_mod")
+ cacheDir := repoPath("internal/fetch/testdata/modcache")
flag.Set("static", repoPath("static"))
testModules := proxytest.LoadTestModules(repoPath("internal/proxy/testdata"))
prox, teardown := proxytest.SetupTestClient(t, testModules)
defer teardown()
- server, err := newServer(context.Background(), []string{localModule}, false, prox)
+ server, err := newServer(context.Background(), []string{localModule}, false, cacheDir, prox)
if err != nil {
t.Fatal(err)
}
mux := http.NewServeMux()
server.Install(mux.Handle, nil, nil)
- w := httptest.NewRecorder()
- for _, url := range []string{"/example.com/testmod", "/example.com/single/pkg"} {
- mux.ServeHTTP(w, httptest.NewRequest("GET", url, nil))
- if w.Code != http.StatusOK {
- t.Errorf("%q: got status code = %d, want %d", url, w.Code, http.StatusOK)
- }
+ for _, test := range []struct {
+ name string
+ url string
+ wantInBody string
+ }{
+ {"local", "example.com/testmod", "There is no documentation for this package."},
+ {"modcache", "modcache.com@v1.0.0", "var V = 1"},
+ {"proxy", "example.com/single/pkg", "G is new in v1.1.0"},
+ } {
+ t.Run(test.name, func(t *testing.T) {
+ w := httptest.NewRecorder()
+ mux.ServeHTTP(w, httptest.NewRequest("GET", "/"+test.url, nil))
+ if w.Code != http.StatusOK {
+ t.Fatalf("got status code = %d, want %d", w.Code, http.StatusOK)
+ }
+ body := w.Body.String()
+ if !strings.Contains(body, test.wantInBody) {
+ t.Fatalf("body is missing %q\n%s", test.wantInBody, body)
+ }
+ })
}
}
diff --git a/internal/fetch/testdata/modcache/modcache.com/@v/README b/internal/fetch/testdata/modcache/modcache.com/@v/README
new file mode 100644
index 0000000..db70aeb
--- /dev/null
+++ b/internal/fetch/testdata/modcache/modcache.com/@v/README
@@ -0,0 +1 @@
+This module exists only in this module cache.
\ No newline at end of file
diff --git a/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.info b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.info
new file mode 100644
index 0000000..2e4d188
--- /dev/null
+++ b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.info
@@ -0,0 +1 @@
+{"Version":"v1.0.0","Time":"2019-03-30T17:04:38Z"}
\ No newline at end of file
diff --git a/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.mod b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.mod
new file mode 100644
index 0000000..fdba8cd
--- /dev/null
+++ b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.mod
@@ -0,0 +1,3 @@
+module modcache.com
+
+go 1.12
diff --git a/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.zip b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.zip
new file mode 100644
index 0000000..5bfaec8
--- /dev/null
+++ b/internal/fetch/testdata/modcache/modcache.com/@v/v1.0.0.zip
Binary files differ
diff --git a/internal/fetchdatasource/fetchdatasource.go b/internal/fetchdatasource/fetchdatasource.go
index 30115a4..84b44c1 100644
--- a/internal/fetchdatasource/fetchdatasource.go
+++ b/internal/fetchdatasource/fetchdatasource.go
@@ -251,7 +251,7 @@
}
if latestUnitMeta == nil {
- latestUnitMeta, err = ds.GetUnitMeta(ctx, unitPath, internal.UnknownModulePath, version.Latest)
+ latestUnitMeta, err = ds.GetUnitMeta(ctx, unitPath, modulePath, version.Latest)
if err != nil {
return latest, err
}