cmd/pkgsite: refactor and add test
Create all the getters in one place so we can test that.
Change-Id: I748a823562ee6e247ea9eece8e77d65bc68d68d4
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/386195
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/cmd/pkgsite/main.go b/cmd/pkgsite/main.go
index 43e2786..0ec7626 100644
--- a/cmd/pkgsite/main.go
+++ b/cmd/pkgsite/main.go
@@ -134,7 +134,11 @@
}
}
- server, err := newServer(ctx, paths, *gopathMode, modCacheDir, cacheMods, prox)
+ getters, err := buildGetters(ctx, paths, *gopathMode, modCacheDir, cacheMods, prox)
+ if err != nil {
+ die("%s", err)
+ }
+ server, err := newServer(getters, prox)
if err != nil {
die("%s", err)
}
@@ -145,12 +149,6 @@
die("%v", http.ListenAndServe(*httpAddr, mw(router)))
}
-func die(format string, args ...interface{}) {
- fmt.Fprintf(os.Stderr, format, args...)
- fmt.Fprintln(os.Stderr)
- os.Exit(1)
-}
-
func collectPaths(args []string) []string {
var paths []string
for _, arg := range args {
@@ -159,8 +157,8 @@
return paths
}
-func newServer(ctx context.Context, paths []string, gopathMode bool, downloadDir string, cacheMods []internal.Modver, prox *proxy.Client) (*frontend.Server, error) {
- getters := buildGetters(ctx, paths, gopathMode)
+func buildGetters(ctx context.Context, paths []string, gopathMode bool, downloadDir string, cacheMods []internal.Modver, prox *proxy.Client) ([]fetch.ModuleGetter, error) {
+ getters := buildPathGetters(ctx, paths, gopathMode)
if downloadDir != "" {
g, err := fetch.NewFSProxyModuleGetter(downloadDir, cacheMods)
if err != nil {
@@ -171,30 +169,10 @@
if prox != nil {
getters = append(getters, fetch.NewProxyModuleGetter(prox, source.NewClient(time.Second)))
}
- lds := fetchdatasource.Options{
- Getters: getters,
- ProxyClientForLatest: prox,
- BypassLicenseCheck: true,
- }.New()
- server, err := frontend.NewServer(frontend.ServerConfig{
- DataSourceGetter: func(context.Context) internal.DataSource { return lds },
- TemplateFS: template.TrustedFSFromEmbed(static.FS),
- StaticFS: static.FS,
- ThirdPartyFS: thirdparty.FS,
- })
- if err != nil {
- return nil, err
- }
- for _, g := range getters {
- p, fsys := g.SourceFS()
- if p != "" {
- server.InstallFS(p, fsys)
- }
- }
- return server, nil
+ return getters, nil
}
-func buildGetters(ctx context.Context, paths []string, gopathMode bool) []fetch.ModuleGetter {
+func buildPathGetters(ctx context.Context, paths []string, gopathMode bool) []fetch.ModuleGetter {
var getters []fetch.ModuleGetter
loaded := len(paths)
for _, path := range paths {
@@ -221,6 +199,30 @@
return getters
}
+func newServer(getters []fetch.ModuleGetter, prox *proxy.Client) (*frontend.Server, error) {
+ lds := fetchdatasource.Options{
+ Getters: getters,
+ ProxyClientForLatest: prox,
+ BypassLicenseCheck: true,
+ }.New()
+ server, err := frontend.NewServer(frontend.ServerConfig{
+ DataSourceGetter: func(context.Context) internal.DataSource { return lds },
+ TemplateFS: template.TrustedFSFromEmbed(static.FS),
+ StaticFS: static.FS,
+ ThirdPartyFS: thirdparty.FS,
+ })
+ if err != nil {
+ return nil, err
+ }
+ for _, g := range getters {
+ p, fsys := g.SourceFS()
+ if p != "" {
+ server.InstallFS(p, fsys)
+ }
+ }
+ return server, nil
+}
+
func defaultCacheDir() (string, error) {
out, err := runGo("", "env", "GOMODCACHE")
if err != nil {
@@ -282,3 +284,9 @@
}
return outPaths, cacheMods, nil
}
+
+func die(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, format, args...)
+ fmt.Fprintln(os.Stderr)
+ os.Exit(1)
+}
diff --git a/cmd/pkgsite/main_test.go b/cmd/pkgsite/main_test.go
index 86d5cab..a0dfac3 100644
--- a/cmd/pkgsite/main_test.go
+++ b/cmd/pkgsite/main_test.go
@@ -17,6 +17,7 @@
"github.com/google/go-cmp/cmp"
"golang.org/x/net/html"
"golang.org/x/pkgsite/internal"
+ "golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/proxy/proxytest"
"golang.org/x/pkgsite/internal/testing/htmlcheck"
)
@@ -32,7 +33,82 @@
}
)
-func Test(t *testing.T) {
+func TestBuildGetters(t *testing.T) {
+ repoPath := func(fn string) string { return filepath.Join("..", "..", fn) }
+
+ abs := func(dir string) string {
+ a, err := filepath.Abs(dir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return a
+ }
+
+ ctx := context.Background()
+ localModule := repoPath("internal/fetch/testdata/has_go_mod")
+ cacheDir := repoPath("internal/fetch/testdata/modcache")
+ testModules := proxytest.LoadTestModules(repoPath("internal/proxy/testdata"))
+ prox, teardown := proxytest.SetupTestClient(t, testModules)
+ defer teardown()
+
+ localGetter := "Dir(example.com/testmod, " + abs(localModule) + ")"
+ cacheGetter := "FSProxy(" + abs(cacheDir) + ")"
+ for _, test := range []struct {
+ name string
+ paths []string
+ cmods []internal.Modver
+ cacheDir string
+ prox *proxy.Client
+ want []string
+ }{
+ {
+ name: "local only",
+ paths: []string{localModule},
+ want: []string{localGetter},
+ },
+ {
+ name: "cache",
+ cacheDir: cacheDir,
+ want: []string{cacheGetter},
+ },
+ {
+ name: "proxy",
+ prox: prox,
+ want: []string{"Proxy"},
+ },
+ {
+ name: "all three",
+ paths: []string{localModule},
+ cacheDir: cacheDir,
+ prox: prox,
+ want: []string{localGetter, cacheGetter, "Proxy"},
+ },
+ {
+ name: "list",
+ paths: []string{localModule},
+ cacheDir: cacheDir,
+ cmods: []internal.Modver{{Path: "foo", Version: "v1.2.3"}},
+ want: []string{localGetter, "FSProxy(" + abs(cacheDir) + ", foo@v1.2.3)"},
+ },
+ } {
+ t.Run(test.name, func(t *testing.T) {
+ getters, err := buildGetters(ctx, test.paths, false, test.cacheDir, test.cmods, test.prox)
+ if err != nil {
+ t.Fatal(err)
+ }
+ var got []string
+ for _, g := range getters {
+ got = append(got, g.String())
+ }
+
+ if diff := cmp.Diff(test.want, got); diff != "" {
+ t.Errorf("mismatch (-want, +got):\n%s", diff)
+ }
+ })
+ }
+}
+
+func TestServer(t *testing.T) {
repoPath := func(fn string) string { return filepath.Join("..", "..", fn) }
abs := func(dir string) string {
@@ -49,7 +125,8 @@
prox, teardown := proxytest.SetupTestClient(t, testModules)
defer teardown()
- server, err := newServer(context.Background(), []string{localModule}, false, cacheDir, nil, prox)
+ getters, err := buildGetters(context.Background(), []string{localModule}, false, cacheDir, nil, prox)
+ server, err := newServer(getters, prox)
if err != nil {
t.Fatal(err)
}
diff --git a/internal/fetch/getters.go b/internal/fetch/getters.go
index 4fb74ef..8760747 100644
--- a/internal/fetch/getters.go
+++ b/internal/fetch/getters.go
@@ -18,6 +18,7 @@
"os"
"path"
"path/filepath"
+ "sort"
"strings"
"time"
@@ -54,6 +55,9 @@
// returned values are intended to be passed to
// internal/frontend.Server.InstallFiles.
SourceFS() (string, fs.FS)
+
+ // String returns a representation of the getter for testing and debugging.
+ String() string
}
type proxyModuleGetter struct {
@@ -96,6 +100,10 @@
return "", nil
}
+func (g *proxyModuleGetter) String() string {
+ return "Proxy"
+}
+
// Version and commit time are pre specified when fetching a local module, as these
// fields are normally obtained from a proxy.
var (
@@ -190,6 +198,11 @@
return path.Join(filepath.ToSlash(g.dir), g.modulePath)
}
+// For testing.
+func (g *directoryModuleGetter) String() string {
+ return fmt.Sprintf("Dir(%s, %s)", g.modulePath, g.dir)
+}
+
// An fsProxyModuleGetter gets modules from a directory in the filesystem that
// is organized like the module cache, with a cache/download directory that has
// paths that correspond to proxy URLs. An example of such a directory is
@@ -384,3 +397,16 @@
}
return filepath.Join(g.dir, "cache", "download", filepath.FromSlash(ep), "@v"), nil
}
+
+// For testing.
+func (g *fsProxyModuleGetter) String() string {
+ if g.allowed == nil {
+ return fmt.Sprintf("FSProxy(%s)", g.dir)
+ }
+ var as []string
+ for a := range g.allowed {
+ as = append(as, a.String())
+ }
+ sort.Strings(as)
+ return fmt.Sprintf("FSProxy(%s, %s)", g.dir, strings.Join(as, ","))
+}