From e3930c6fe54ef10cd81db6ba918a42bc389f2969 Mon Sep 17 00:00:00 2001 From: Suhas Karanth Date: Tue, 3 Oct 2017 10:02:46 +0530 Subject: [PATCH] allow cachedir override using env var - main - Read and use env var `DEPCACHEDIR` for instantiating dep context. - context - Add field `Cachedir` to struct `Ctx`. This holds the value of env var `DEPCACHEDIR`. - Use `Ctx.Cachedir` while instantiating `gps.SourceMgr` if present, fallback to `$GOPATH/pkg/dep` otherwise. - source_manager - Add a getter func `Cachedir` to facilitate testing in `context_test.go`. - context_test - Add test to check `gps.SourceMgr` is instantiated with appropriate `cachedir`. - integration_test - Add test to check environment variable `DEPCACHEDIR` is loaded and used if present. --- cmd/dep/integration_test.go | 40 ++++++++++++++++++++++++++++ cmd/dep/main.go | 5 ++++ cmd/dep/testdata/cachedir/Gopkg.lock | 15 +++++++++++ cmd/dep/testdata/cachedir/Gopkg.toml | 4 +++ cmd/dep/testdata/cachedir/main.go | 12 +++++++++ context.go | 9 ++++++- context_test.go | 39 +++++++++++++++++++++++++++ internal/gps/source_manager.go | 5 ++++ 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 cmd/dep/testdata/cachedir/Gopkg.lock create mode 100644 cmd/dep/testdata/cachedir/Gopkg.toml create mode 100644 cmd/dep/testdata/cachedir/main.go diff --git a/cmd/dep/integration_test.go b/cmd/dep/integration_test.go index 5548cba516..1e0c770de6 100644 --- a/cmd/dep/integration_test.go +++ b/cmd/dep/integration_test.go @@ -52,6 +52,46 @@ func TestIntegration(t *testing.T) { }) } +func TestDepCachedir(t *testing.T) { + t.Parallel() + + test.NeedsExternalNetwork(t) + test.NeedsGit(t) + + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + + initPath := filepath.Join("testdata", "cachedir") + + testProj := integration.NewTestProject(t, initPath, wd, runMain) + defer testProj.Cleanup() + + testProj.TempDir("cachedir") + cachedir := testProj.Path("cachedir") + testProj.Setenv("DEPCACHEDIR", cachedir) + + // Running `dep ensure` will pull in the dependency into cachedir. + err = testProj.DoRun([]string{"ensure"}) + if err != nil { + // Log the error output from running `dep ensure`, could be useful. + t.Log(testProj.GetStderr()) + t.Fatalf("got an unexpected error: %s", err.Error()) + } + + // Check that the cache was created in the cachedir. Our fixture has the dependency + // `github.com/sdboyer/deptest` + _, err = os.Stat(testProj.Path("cachedir", "sources", "https---github.com-sdboyer-deptest")) + if err != nil { + if os.IsNotExist(err) { + t.Fatal("Expected cachedir to have been populated but none was found") + } else { + t.Fatalf("Got unexpected error: %s", err) + } + } +} + // execCmd is a test.RunFunc which runs the program in another process. func execCmd(prog string, args []string, stdout, stderr io.Writer, dir string, env []string) error { cmd := exec.Command(prog, args...) diff --git a/cmd/dep/main.go b/cmd/dep/main.go index f465197028..34fcd7a1cb 100644 --- a/cmd/dep/main.go +++ b/cmd/dep/main.go @@ -145,12 +145,17 @@ func (c *Config) Run() (exitCode int) { return } + // Cachedir is loaded from env if present. `$GOPATH/pkg/dep` is used as the + // fallback cache location. + cachedir := getEnv(c.Env, "DEPCACHEDIR") + // Set up dep context. ctx := &dep.Ctx{ Out: outLogger, Err: errLogger, Verbose: *verbose, DisableLocking: getEnv(c.Env, "DEPNOLOCK") != "", + Cachedir: cachedir, } GOPATHS := filepath.SplitList(getEnv(c.Env, "GOPATH")) diff --git a/cmd/dep/testdata/cachedir/Gopkg.lock b/cmd/dep/testdata/cachedir/Gopkg.lock new file mode 100644 index 0000000000..c7f497e7a1 --- /dev/null +++ b/cmd/dep/testdata/cachedir/Gopkg.lock @@ -0,0 +1,15 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/sdboyer/deptest" + packages = ["."] + revision = "ff2948a2ac8f538c4ecd55962e919d1e13e74baf" + version = "v1.0.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "14b07b05e0f01051b03887ab2bf80b516bc5510ea92f75f76c894b1745d8850c" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/cmd/dep/testdata/cachedir/Gopkg.toml b/cmd/dep/testdata/cachedir/Gopkg.toml new file mode 100644 index 0000000000..e242e02114 --- /dev/null +++ b/cmd/dep/testdata/cachedir/Gopkg.toml @@ -0,0 +1,4 @@ + +[[constraint]] + name = "github.com/sdboyer/deptest" + version = "1.0.0" diff --git a/cmd/dep/testdata/cachedir/main.go b/cmd/dep/testdata/cachedir/main.go new file mode 100644 index 0000000000..1fe0d19d6a --- /dev/null +++ b/cmd/dep/testdata/cachedir/main.go @@ -0,0 +1,12 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + _ "github.com/sdboyer/deptest" +) + +func main() { +} diff --git a/context.go b/context.go index ba8007360e..76a4aaa327 100644 --- a/context.go +++ b/context.go @@ -40,6 +40,7 @@ type Ctx struct { Out, Err *log.Logger // Required loggers. Verbose bool // Enables more verbose logging. DisableLocking bool // When set, no lock file will be created to protect against simultaneous dep processes. + Cachedir string // Cache directory loaded from environment. } // SetPaths sets the WorkingDir and GOPATHs fields. If GOPATHs is empty, then @@ -87,8 +88,14 @@ func defaultGOPATH() string { // SourceManager produces an instance of gps's built-in SourceManager // initialized to log to the receiver's logger. func (c *Ctx) SourceManager() (*gps.SourceMgr, error) { + cachedir := c.Cachedir + if cachedir == "" { + // When `DEPCACHEDIR` isn't set in the env, fallback to `$GOPATH/pkg/dep`. + cachedir = filepath.Join(c.GOPATH, "pkg", "dep") + } + return gps.NewSourceManager(gps.SourceManagerConfig{ - Cachedir: filepath.Join(c.GOPATH, "pkg", "dep"), + Cachedir: cachedir, Logger: c.Out, DisableLocking: c.DisableLocking, }) diff --git a/context_test.go b/context_test.go index 7e5eda6e25..4628d59691 100644 --- a/context_test.go +++ b/context_test.go @@ -485,3 +485,42 @@ func TestDetectGOPATH(t *testing.T) { } } } + +func TestDepCachedir(t *testing.T) { + h := test.NewHelper(t) + defer h.Cleanup() + + h.TempDir("cache") + // Create the directory for fallback cachedir location. + h.TempDir(filepath.Join("go", "pkg", "dep")) + + testCachedir := h.Path("cache") + gopath := h.Path("go") + discardLgr := discardLogger() + + cases := []struct { + cachedir string + wantCachedir string + }{ + // If `Cachedir` is not set in the context, it should use `$GOPATH/pkg/dep`. + {cachedir: "", wantCachedir: h.Path(filepath.Join("go", "pkg", "dep"))}, + // If `Cachedir` is set in the context, it should use that. + {cachedir: testCachedir, wantCachedir: testCachedir}, + } + + for _, c := range cases { + ctx := &Ctx{ + GOPATH: gopath, + Cachedir: c.cachedir, + Out: discardLgr, + Err: discardLgr, + } + sm, err := ctx.SourceManager() + h.Must(err) + defer sm.Release() + + if sm.Cachedir() != c.wantCachedir { + t.Errorf("expected cachedir to be %s, got %s", c.wantCachedir, sm.Cachedir()) + } + } +} diff --git a/internal/gps/source_manager.go b/internal/gps/source_manager.go index 23f3c1c8b5..8e655a506d 100644 --- a/internal/gps/source_manager.go +++ b/internal/gps/source_manager.go @@ -292,6 +292,11 @@ func NewSourceManager(c SourceManagerConfig) (*SourceMgr, error) { return sm, nil } +// Cachedir returns the location of the cache directory. +func (sm *SourceMgr) Cachedir() string { + return sm.cachedir +} + // UseDefaultSignalHandling sets up typical os.Interrupt signal handling for a // SourceMgr. func (sm *SourceMgr) UseDefaultSignalHandling() {