From e7525a43b47c881e6801b05cd4789ca1ff07d5e9 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 4 Jun 2018 16:55:40 -0400 Subject: [PATCH 1/3] dep: Allow explicitly setting the project root This is potentially useful when working on projects that aren't compiled by the standard toolchain (e.g., by Bazel), and thus don't need to live within a GOPATH. It also comports with the upcoming changes to do away with GOPATH. --- context.go | 22 ++++++++++++---- context_test.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/context.go b/context.go index 9dc33dc30f..d5c7c6b4bb 100644 --- a/context.go +++ b/context.go @@ -38,6 +38,7 @@ type Ctx struct { WorkingDir string // Where to execute. GOPATH string // Selected Go path, containing WorkingDir. GOPATHs []string // Other Go paths. + ExplicitRoot string // An explicitly-set path to use as the project root. 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. @@ -63,6 +64,8 @@ func (c *Ctx) SetPaths(wd string, GOPATHs ...string) error { c.GOPATHs = append(c.GOPATHs, GOPATHs...) + c.ExplicitRoot = os.Getenv("DEP_PROJECT_ROOT") + return nil } @@ -137,11 +140,15 @@ func (c *Ctx) LoadProject() (*Project, error) { return nil, err } - ip, err := c.ImportForAbs(p.AbsRoot) - if err != nil { - return nil, errors.Wrap(err, "root project import") + if c.ExplicitRoot != "" { + p.ImportRoot = gps.ProjectRoot(c.ExplicitRoot) + } else { + ip, err := c.ImportForAbs(p.AbsRoot) + if err != nil { + return nil, errors.Wrap(err, "root project import") + } + p.ImportRoot = gps.ProjectRoot(ip) } - p.ImportRoot = gps.ProjectRoot(ip) mp := filepath.Join(p.AbsRoot, ManifestName) mf, err := os.Open(mp) @@ -202,9 +209,14 @@ func (c *Ctx) DetectProjectGOPATH(p *Project) (string, error) { return "", errors.New("project AbsRoot and ResolvedAbsRoot must be set to detect GOPATH") } + if c.ExplicitRoot != "" { + // If an explicit root is set, just use the first GOPATH in the list. + return c.GOPATHs[0], nil + } + pGOPATH, perr := c.detectGOPATH(p.AbsRoot) - // If p.AbsRoot is a not symlink, attempt to detect GOPATH for p.AbsRoot only. + // If p.AbsRoot is a not a symlink, attempt to detect GOPATH for p.AbsRoot only. if equal, _ := fs.EquivalentPaths(p.AbsRoot, p.ResolvedAbsRoot); equal { return pGOPATH, perr } diff --git a/context_test.go b/context_test.go index d673cc845a..ced325c759 100644 --- a/context_test.go +++ b/context_test.go @@ -152,6 +152,69 @@ func TestLoadProject(t *testing.T) { } } +func TestExplicitRootProject(t *testing.T) { + h := test.NewHelper(t) + defer h.Cleanup() + + h.TempDir(filepath.Join("src", "test1", "sub")) + h.TempFile(filepath.Join("src", "test1", ManifestName), "") + h.TempFile(filepath.Join("src", "test1", LockName), `memo = "cdafe8641b28cd16fe025df278b0a49b9416859345d8b6ba0ace0272b74925ee"`) + h.TempDir(filepath.Join("src", "test2", "sub")) + h.TempFile(filepath.Join("src", "test2", ManifestName), "") + h.Setenv("DEP_PROJECT_ROOT", "github.com/user/module") + + type tcase struct { + name string + lock bool + wd string + } + var testcases = []tcase{ + {"direct", true, filepath.Join("src", "test1")}, + {"ascending", true, filepath.Join("src", "test1", "sub")}, + {"without lock", false, filepath.Join("src", "test2")}, + {"ascending without lock", false, filepath.Join("src", "test2", "sub")}, + } + + tf := func(withGOPATH bool, tc tcase, t *testing.T) func(t *testing.T) { + return func(t *testing.T) { + ctx := &Ctx{ + Out: discardLogger(), + Err: discardLogger(), + } + + var err error + if withGOPATH { + err = ctx.SetPaths(h.Path(tc.wd), h.Path(".")) + } else { + err = ctx.SetPaths(h.Path(tc.wd)) + } + if err != nil { + t.Fatalf("%+v", err) + } + ctx.ExplicitRoot = "github.com/user/module" + + p, err := ctx.LoadProject() + switch { + case err != nil: + t.Fatalf("%s: LoadProject failed: %+v", tc.wd, err) + case p.Manifest == nil: + t.Fatalf("%s: Manifest file didn't load", tc.wd) + case tc.lock && p.Lock == nil: + t.Fatalf("%s: Lock file didn't load", tc.wd) + case !tc.lock && p.Lock != nil: + t.Fatalf("%s: Non-existent Lock file loaded", tc.wd) + } + } + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + t.Run("within-GOPATH", tf(true, tc, t)) + t.Run("outside-GOPATH", tf(false, tc, t)) + }) + } +} + func TestLoadProjectNotFoundErrors(t *testing.T) { tg := test.NewHelper(t) defer tg.Cleanup() @@ -313,9 +376,9 @@ func TestLoadProjectGopkgFilenames(t *testing.T) { } } -// TestCaseInsentitive is test for Windows. This should work even though set +// TestCaseInsensitive is test for Windows. This should work even though set // difference letter cases in GOPATH. -func TestCaseInsentitiveGOPATH(t *testing.T) { +func TestCaseInsensitiveGOPATH(t *testing.T) { if runtime.GOOS != "windows" { t.Skip("skip this test on non-Windows") } From 8e01b93f40fb466a21058bb7277cec8e64fbfe01 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 4 Jun 2018 21:43:56 -0400 Subject: [PATCH 2/3] dep: Add DEPPROJECTROOT CHANGELOG entry and docs --- CHANGELOG.md | 18 ++++++++---------- docs/env-vars.md | 32 ++++++++++++++++++++++++++++++++ docs/glossary.md | 2 +- website/sidebars.json | 2 +- 4 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 docs/env-vars.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f30cb39834..15463b6326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,24 +2,22 @@ NEW FEATURES: -* Add CI tests against go1.10. Drop support for go1.8. ([#1620](https://github.com/golang/dep/pull/1620)) -* Added `install.sh` script. ([#1533](https://github.com/golang/dep/pull/1533)) -* List out of date projects in dep status. ([#1553](https://github.com/golang/dep/pull/1553)). -* Enabled opt-in persistent caching via $DEPCACHEAGE env var. ([#1711](https://github.com/golang/dep/pull/1711)) +* Add CI tests against go1.10. Drop support for go1.8. ([#1620](https://github.com/golang/dep/pull/1620)). +* Added `install.sh` script. ([#1533](https://github.com/golang/dep/pull/1533)). +* List out of date projects in dep status ([#1553](https://github.com/golang/dep/pull/1553)). +* Enabled opt-in persistent caching via `DEPCACHEAGE` env var. ([#1711](https://github.com/golang/dep/pull/1711)). +* Allow `DEPPROJECTROOT` [environment variable](https://golang.github.io/dep/docs/env-vars.html#depprojectroot) to supersede GOPATH deduction and explicitly set the current project's [root](https://golang.github.io/dep/docs/glossary.html#project-root) ([#1883](https://github.com/golang/dep/pull/1883)). BUG FIXES: IMPROVEMENTS: -* Add template operations support in dep status template output. -([#1549](https://github.com/golang/dep/pull/1549)). -* Reduce network access by trusting local source information and only pulling -from upstream when necessary ([#1250](https://github.com/golang/dep/pull/1250)). +* Add template operations support in dep status template output ([#1549](https://github.com/golang/dep/pull/1549)). +* Reduce network access by trusting local source information and only pulling from upstream when necessary ([#1250](https://github.com/golang/dep/pull/1250)). * Update our dependency on Masterminds/semver to follow upstream again now that [Masterminds/semver#67](https://github.com/Masterminds/semver/pull/67) is merged([#1792](https://github.com/golang/dep/pull/1792)). WIP: -* Enable importing external configuration from dependencies during init (#1277). This -is feature flagged and disabled by default. +* Enable importing external configuration from dependencies during init (#1277). This is feature flagged and disabled by default. # v0.4.1 diff --git a/docs/env-vars.md b/docs/env-vars.md new file mode 100644 index 0000000000..83aeed9218 --- /dev/null +++ b/docs/env-vars.md @@ -0,0 +1,32 @@ +--- +id: env-vars +title: Environment Variables +--- + +dep's behavior can be modified by some environment variables: + +* [`DEPCACHEDIR`](#depcachedir) +* [`DEPPROJECTROOT`](#depprojectroot) +* [`DEPNOLOCK`](#depnolock) + +Environment variables are passed through to subcommands, and therefore can be used to affect vcs (e.g. `git`) behavior. + +--- + +### `DEPCACHEDIR` + +Allows the user to specify a custom directory for dep's [local cache](glossary.md#local-cache) of pristine VCS source repositories. Defaults to `$GOPATH/pkg/dep`. + +### `DEPPROJECTROOT` + +If set, the value of this variable will be treated as the [project root](glossary.md#project-root) of the [current project](glossary.md#current-project), superseding GOPATH-based inference. + +This is primarily useful if you're not using the standard `go` toolchain as a compiler (for example, with Bazel), as there otherwise isn't much use to operating outside of GOPATH. + +### `DEPNOLOCK` + +By default, dep creates an `sm.lock` file at `$DEPCACHEDIR/sm.lock` in order to +prevent multiple dep processes from interacting with the [local +cache](glossary.md#local-cache) simultaneously. Setting this variable will +bypass that protection; no file will be created. This can be useful on certain +filesystems; VirtualBox shares in particular are known to misbehave. diff --git a/docs/glossary.md b/docs/glossary.md index b982f23bdf..9c491aa211 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -75,7 +75,7 @@ Stands for "Go packaging solver", it is [a subtree of library-style packages wit dep maintains its own, pristine set of upstream sources (so, generally, git repository clones). This is kept separate from `$GOPATH/src` so that there is no obligation to maintain disk state within `$GOPATH`, as dep frequently needs to change disk state in order to do its work. -By default, the local cache lives at `$GOPATH/pkg/dep`. If you have multiple `$GOPATH` entries, dep will use whichever is the logical parent of the process' working directory. Alternatively, the location can be forced via the `DEPCACHEDIR` environment variable. +By default, the local cache lives at `$GOPATH/pkg/dep`. If you have multiple `$GOPATH` entries, dep will use whichever is the logical parent of the process' working directory. Alternatively, the location can be forced via the [`DEPCACHEDIR` environment variable](env-vars.md#depcachedir). ### Lock diff --git a/website/sidebars.json b/website/sidebars.json index 962d2bc622..ca1a4762e3 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -1,6 +1,6 @@ { "docs": { "Guides": ["introduction", "installation", "new-project", "migrating", "daily-dep"], - "References": ["ensure-mechanics", "failure-modes", "the-solver", "deduction", "Gopkg.toml", "Gopkg.lock", "FAQ", "glossary"] + "References": ["ensure-mechanics", "failure-modes", "the-solver", "deduction", "Gopkg.toml", "Gopkg.lock", "FAQ", "env-vars", "glossary"] } } From 5e1f5d4ddd05968d0a39707af571950be5762ac0 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 4 Jun 2018 21:49:31 -0400 Subject: [PATCH 3/3] dep: Change DEP_PROJECT_ROOT to DEPPROJECTROOT --- context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/context.go b/context.go index d5c7c6b4bb..d7b403ab8c 100644 --- a/context.go +++ b/context.go @@ -64,7 +64,7 @@ func (c *Ctx) SetPaths(wd string, GOPATHs ...string) error { c.GOPATHs = append(c.GOPATHs, GOPATHs...) - c.ExplicitRoot = os.Getenv("DEP_PROJECT_ROOT") + c.ExplicitRoot = os.Getenv("DEPPROJECTROOT") return nil }