diff --git a/cmd/dep/gopath_scanner.go b/cmd/dep/gopath_scanner.go index d672a4de04..b04e368e2a 100644 --- a/cmd/dep/gopath_scanner.go +++ b/cmd/dep/gopath_scanner.go @@ -219,7 +219,12 @@ func (g *gopathScanner) scanGopathForDependencies() (projectData, error) { go syncDep(pr, g.sm) dependencies[pr] = []string{ip} - v, err := g.ctx.VersionInWorkspace(pr) + abs, err := g.ctx.AbsForImport(string(pr)) + if err != nil { + notondisk[pr] = true + continue + } + v, err := gps.VCSVersion(abs) if err != nil { notondisk[pr] = true continue @@ -283,7 +288,13 @@ func (g *gopathScanner) scanGopathForDependencies() (projectData, error) { // was found in the initial pass on direct imports. We know it's // the former if there's no entry for it in the ondisk map. if _, in := ondisk[pr]; !in { - v, err := g.ctx.VersionInWorkspace(pr) + abs, err := g.ctx.AbsForImport(string(pr)) + if err != nil { + colors[pkg] = black + notondisk[pr] = true + return nil + } + v, err := gps.VCSVersion(abs) if err != nil { // Even if we know it's on disk, errors are still // possible when trying to deduce version. If we diff --git a/context.go b/context.go index cec883133b..39b85b95a3 100644 --- a/context.go +++ b/context.go @@ -9,9 +9,7 @@ import ( "os" "path/filepath" "runtime" - "strings" - "github.com/Masterminds/vcs" "github.com/golang/dep/internal/fs" "github.com/golang/dep/internal/gps" "github.com/pkg/errors" @@ -236,10 +234,10 @@ func (c *Ctx) ImportForAbs(path string) (string, error) { return "", errors.Errorf("%s not in GOPATH", path) } -// absoluteProjectRoot determines the absolute path to the project root +// AbsForImport returns the absolute path for the project root // including the $GOPATH. This will not work with stdlib packages and the // package directory needs to exist. -func (c *Ctx) absoluteProjectRoot(path string) (string, error) { +func (c *Ctx) AbsForImport(path string) (string, error) { posspath := filepath.Join(c.GOPATH, "src", path) dirOK, err := fs.IsDir(posspath) if err != nil { @@ -250,62 +248,3 @@ func (c *Ctx) absoluteProjectRoot(path string) (string, error) { } return posspath, nil } - -func (c *Ctx) VersionInWorkspace(root gps.ProjectRoot) (gps.Version, error) { - pr, err := c.absoluteProjectRoot(string(root)) - if err != nil { - return nil, errors.Wrapf(err, "determine project root for %s", root) - } - - repo, err := vcs.NewRepo("", pr) - if err != nil { - return nil, errors.Wrapf(err, "creating new repo for root: %s", pr) - } - - ver, err := repo.Current() - if err != nil { - return nil, errors.Wrapf(err, "finding current branch/version for root: %s", pr) - } - - rev, err := repo.Version() - if err != nil { - return nil, errors.Wrapf(err, "getting repo version for root: %s", pr) - } - - // First look through tags. - tags, err := repo.Tags() - if err != nil { - return nil, errors.Wrapf(err, "getting repo tags for root: %s", pr) - } - // Try to match the current version to a tag. - if contains(tags, ver) { - // Assume semver if it starts with a v. - if strings.HasPrefix(ver, "v") { - return gps.NewVersion(ver).Pair(gps.Revision(rev)), nil - } - - return nil, errors.Errorf("version for root %s does not start with a v: %q", pr, ver) - } - - // Look for the current branch. - branches, err := repo.Branches() - if err != nil { - return nil, errors.Wrapf(err, "getting repo branch for root: %s") - } - // Try to match the current version to a branch. - if contains(branches, ver) { - return gps.NewBranch(ver).Pair(gps.Revision(rev)), nil - } - - return gps.Revision(rev), nil -} - -// contains checks if a array of strings contains a value -func contains(a []string, b string) bool { - for _, v := range a { - if b == v { - return true - } - } - return false -} diff --git a/context_test.go b/context_test.go index 4ce9c0521d..e522d25b4d 100644 --- a/context_test.go +++ b/context_test.go @@ -14,7 +14,6 @@ import ( "testing" "unicode" - "github.com/golang/dep/internal/gps" "github.com/golang/dep/internal/test" ) @@ -81,7 +80,7 @@ func TestAbsoluteProjectRoot(t *testing.T) { } for i, ok := range importPaths { - got, err := depCtx.absoluteProjectRoot(i) + got, err := depCtx.AbsForImport(i) if ok { h.Must(err) want := h.Path(filepath.Join("src", i)) @@ -98,57 +97,12 @@ func TestAbsoluteProjectRoot(t *testing.T) { // test that a file fails h.TempFile("src/thing/thing.go", "hello world") - _, err := depCtx.absoluteProjectRoot("thing/thing.go") + _, err := depCtx.AbsForImport("thing/thing.go") if err == nil { t.Fatal("error should not be nil for a file found") } } -func TestVersionInWorkspace(t *testing.T) { - test.NeedsExternalNetwork(t) - test.NeedsGit(t) - - h := test.NewHelper(t) - defer h.Cleanup() - - h.TempDir("src") - h.Setenv("GOPATH", h.Path(".")) - depCtx := &Ctx{GOPATH: h.Path(".")} - - importPaths := map[string]struct { - rev gps.Version - checkout bool - }{ - "github.com/pkg/errors": { - rev: gps.NewVersion("v0.8.0").Pair("645ef00459ed84a119197bfb8d8205042c6df63d"), // semver - checkout: true, - }, - "github.com/Sirupsen/logrus": { - rev: gps.Revision("42b84f9ec624953ecbf81a94feccb3f5935c5edf"), // random sha - checkout: true, - }, - "github.com/rsc/go-get-default-branch": { - rev: gps.NewBranch("another-branch").Pair("8e6902fdd0361e8fa30226b350e62973e3625ed5"), - }, - } - - // checkout the specified revisions - for ip, info := range importPaths { - h.RunGo("get", ip) - repoDir := h.Path("src/" + ip) - if info.checkout { - h.RunGit(repoDir, "checkout", info.rev.String()) - } - - got, err := depCtx.VersionInWorkspace(gps.ProjectRoot(ip)) - h.Must(err) - - if got != info.rev { - t.Fatalf("expected %q, got %q", got.String(), info.rev.String()) - } - } -} - func TestLoadProject(t *testing.T) { h := test.NewHelper(t) defer h.Cleanup() diff --git a/internal/gps/vcs_version.go b/internal/gps/vcs_version.go new file mode 100644 index 0000000000..1009337d04 --- /dev/null +++ b/internal/gps/vcs_version.go @@ -0,0 +1,67 @@ +// Copyright 2017 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 gps + +import ( + "strings" + + "github.com/Masterminds/vcs" + "github.com/pkg/errors" +) + +// VCSVersion returns the current project version for an absolute path. +func VCSVersion(path string) (Version, error) { + repo, err := vcs.NewRepo("", path) + if err != nil { + return nil, errors.Wrapf(err, "creating new repo for root: %s", path) + } + + ver, err := repo.Current() + if err != nil { + return nil, errors.Wrapf(err, "finding current branch/version for root: %s", path) + } + + rev, err := repo.Version() + if err != nil { + return nil, errors.Wrapf(err, "getting repo version for root: %s", path) + } + + // First look through tags. + tags, err := repo.Tags() + if err != nil { + return nil, errors.Wrapf(err, "getting repo tags for root: %s", path) + } + // Try to match the current version to a tag. + if contains(tags, ver) { + // Assume semver if it starts with a v. + if strings.HasPrefix(ver, "v") { + return NewVersion(ver).Pair(Revision(rev)), nil + } + + return nil, errors.Errorf("version for root %s does not start with a v: %q", path, ver) + } + + // Look for the current branch. + branches, err := repo.Branches() + if err != nil { + return nil, errors.Wrapf(err, "getting repo branch for root: %s") + } + // Try to match the current version to a branch. + if contains(branches, ver) { + return NewBranch(ver).Pair(Revision(rev)), nil + } + + return Revision(rev), nil +} + +// contains checks if a array of strings contains a value +func contains(a []string, b string) bool { + for _, v := range a { + if b == v { + return true + } + } + return false +} diff --git a/internal/gps/vcs_version_test.go b/internal/gps/vcs_version_test.go new file mode 100644 index 0000000000..7dc11971aa --- /dev/null +++ b/internal/gps/vcs_version_test.go @@ -0,0 +1,57 @@ +// Copyright 2017 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 gps + +import ( + "path/filepath" + "testing" + + "github.com/golang/dep/internal/test" +) + +func TestVCSVersion(t *testing.T) { + test.NeedsExternalNetwork(t) + test.NeedsGit(t) + + h := test.NewHelper(t) + defer h.Cleanup() + + h.TempDir("src") + gopath := h.Path(".") + h.Setenv("GOPATH", gopath) + + importPaths := map[string]struct { + rev Version + checkout bool + }{ + "github.com/pkg/errors": { + rev: NewVersion("v0.8.0").Pair("645ef00459ed84a119197bfb8d8205042c6df63d"), // semver + checkout: true, + }, + "github.com/sirupsen/logrus": { + rev: Revision("42b84f9ec624953ecbf81a94feccb3f5935c5edf"), // random sha + checkout: true, + }, + "github.com/rsc/go-get-default-branch": { + rev: NewBranch("another-branch").Pair("8e6902fdd0361e8fa30226b350e62973e3625ed5"), + }, + } + + // checkout the specified revisions + for ip, info := range importPaths { + h.RunGo("get", ip) + repoDir := h.Path("src/" + ip) + if info.checkout { + h.RunGit(repoDir, "checkout", info.rev.String()) + } + abs := filepath.FromSlash(filepath.Join(gopath, "src", ip)) + got, err := VCSVersion(abs) + h.Must(err) + + if got != info.rev { + t.Fatalf("expected %q, got %q", got.String(), info.rev.String()) + } + } +}