Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

Use evaluated project root path #812

Closed
wants to merge 13 commits into from
4 changes: 2 additions & 2 deletions cmd/dep/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error {
return errors.Errorf("invalid state: manifest %q does not exist, but lock %q does", mf, lf)
}

ip, err := ctx.ImportForAbs(root)
ip, err := ctx.ImportPathForProject(p)
if err != nil {
return errors.Wrap(err, "root project import")
return errors.Wrap(err, "failed to determine import path for project")
}
p.ImportRoot = gps.ProjectRoot(ip)

Expand Down
13 changes: 9 additions & 4 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (c *Ctx) LoadProject() (*Project, error) {
return nil, err
}

ip, err := c.ImportForAbs(p.AbsRoot)
ip, err := c.ImportPathForProject(p)
if err != nil {
return nil, errors.Wrap(err, "root project import")
}
Expand Down Expand Up @@ -217,9 +217,14 @@ func (c *Ctx) detectGOPATH(path string) (string, error) {
return "", errors.Errorf("%s is not within a known GOPATH", path)
}

// ImportForAbs returns the import path for an absolute project path by trimming the
// `$GOPATH/src/` prefix. Returns an error for paths equal to, or without this prefix.
func (c *Ctx) ImportForAbs(path string) (string, error) {
// ImportPathForProject returns the import path for an absolute project path by trimming the
// `GOPATH/src/` prefix. Returns an error for paths equal to, or without this prefix.
func (c *Ctx) ImportPathForProject(p *Project) (string, error) {
path := p.AbsRoot
if p.AbsRoot != p.ResolvedAbsRoot {
path = p.ResolvedAbsRoot
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just do path = p.ResolvedAbsRoot instead?

If they are the same, we did what line 223 is doing. If they are different, we did the if block logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or just use p.ResolvedAbsRoot instead of path...


srcprefix := filepath.Join(c.GOPATH, "src") + string(filepath.Separator)
if fs.HasFilepathPrefix(path, srcprefix) {
if len(path) <= len(srcprefix) {
Expand Down
62 changes: 53 additions & 9 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ func TestCtx_ProjectImport(t *testing.T) {
for _, want := range importPaths {
fullpath := filepath.Join(depCtx.GOPATH, "src", want)
h.TempDir(filepath.Join("src", want))
got, err := depCtx.ImportForAbs(fullpath)

p := &Project{}
if err := p.SetRoot(fullpath); err != nil {
t.Fatal(err)
}
got, err := depCtx.ImportPathForProject(p)

if err != nil {
t.Fatal(err)
}
Expand All @@ -48,15 +54,14 @@ func TestCtx_ProjectImport(t *testing.T) {
}

// test where it should return an error when directly within $GOPATH/src
got, err := depCtx.ImportForAbs(filepath.Join(depCtx.GOPATH, "src"))
if err == nil || !strings.Contains(err.Error(), "GOPATH/src") {
t.Fatalf("should have gotten an error for use directly in GOPATH/src, but got %s", got)
p := &Project{}
if err := p.SetRoot(filepath.Join(depCtx.GOPATH, "src")); err != nil {
t.Fatal(err)
}
got, err := depCtx.ImportPathForProject(p)

// test where it should return an error
got, err = depCtx.ImportForAbs("tra/la/la/la")
if err == nil {
t.Fatalf("should have gotten an error but did not for tra/la/la/la: %s", got)
if err == nil || !strings.Contains(err.Error(), "GOPATH/src") {
t.Fatalf("should have gotten an error for use directly in GOPATH/src, but got %s", got)
}
}

Expand Down Expand Up @@ -301,7 +306,13 @@ func TestCaseInsentitiveGOPATH(t *testing.T) {
ip := "github.com/pkg/errors"
fullpath := filepath.Join(depCtx.GOPATH, "src", ip)
h.TempDir(filepath.Join("src", ip))
pr, err := depCtx.ImportForAbs(fullpath)

p := &Project{}
if err := p.SetRoot(fullpath); err != nil {
t.Fatal(err)
}
pr, err := depCtx.ImportPathForProject(p)

if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -445,3 +456,36 @@ func TestDetectGOPATH(t *testing.T) {
}
}
}

func TestDetectProjectSymlinkedOutsideGOPATH(t *testing.T) {
h := test.NewHelper(t)
defer h.Cleanup()

h.TempDir("src")

h.Setenv("GOPATH", h.Path("."))
depCtx := &Ctx{GOPATH: h.Path(".")}

importPath := "ti/ga/fato/la/večera"
h.TempDir(filepath.Join("src", importPath))
h.TempDir("symlink/to/project")

symlinkSrc := h.OriginalPath(filepath.Join("src", importPath))
symlinkTarget := h.OriginalPath("symlink/to/project/sym")
if err := os.Symlink(symlinkSrc, symlinkTarget); err != nil {
t.Errorf("Error creating symlink from %s to %s: %s", symlinkSrc, symlinkTarget, err.Error())
}
Copy link
Collaborator

@darkowlzz darkowlzz Jul 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since os.Symlink() just returns a single value, let's make it short:

if err := os.Symlink(symlinkSrc, symlinkTarget); err != nil {
	t.Errorf("Error creating symlink from %s to %s: %s", symlinkSrc, symlinkTarget, err.Error())
}


p := Project{}
if err := p.SetRoot(symlinkSrc); err != nil {
t.Fatal(err)
}

got, err := depCtx.ImportPathForProject(&p)
if err != nil {
t.Fatal(err)
}
if got != importPath {
t.Fatalf("expected %s, got %s", importPath, got)
}
}
22 changes: 15 additions & 7 deletions internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,21 @@ func (h *Helper) TempDir(path string) {
}

// Path returns the absolute pathname to file with the temporary
// directory.
// directory. Symlinks are evaluated.
func (h *Helper) Path(name string) string {
path := h.OriginalPath(name)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead keep Path as-is, and make the new function EvalPath or ResolvedPath the one that evaluates symlinks?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibrasho yes, it makes sense. But I'd propose to delay that change after @sdboyer decides if this PR is mergeable or not. Because, this change will just increase the diff by a few hundred lines and increase the possibility of merge conflicts with the current origin/master.

If everything is OK, I'll make sure that the PR with this additional change merges in origin/master without conflicts.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sdboyer What's your opinion?


// Ensure it's the absolute, symlink-less path we're returning
abs, err := filepath.EvalSymlinks(path)
if err != nil {
h.t.Fatalf("%+v", errors.Wrapf(err, "internal testsuite error: could not get absolute path for dir(%q)", path))
}
return abs
}

// OriginalPath returns the absolute pathname to file with the temporary
// directory. Symlinks are NOT evaluated.
func (h *Helper) OriginalPath(name string) string {
if h.tempdir == "" {
h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: path(%q) with no tempdir", name))
}
Expand All @@ -511,12 +524,7 @@ func (h *Helper) Path(name string) string {
joined = filepath.Join(h.tempdir, name)
}

// Ensure it's the absolute, symlink-less path we're returning
abs, err := filepath.EvalSymlinks(joined)
if err != nil {
h.t.Fatalf("%+v", errors.Wrapf(err, "internal testsuite error: could not get absolute path for dir(%q)", joined))
}
return abs
return joined
}

// MustExist fails if path does not exist.
Expand Down