From d688a81d8e7c1cc9fbb54a9fd9c9142c04cf5620 Mon Sep 17 00:00:00 2001 From: Nicholas Katsaros Date: Sat, 15 Jul 2017 16:41:41 -0600 Subject: [PATCH] GOPATH detection now works when GOPATH is a symlink --- context.go | 5 +++++ context_test.go | 20 +++++++++++++++++--- internal/test/test.go | 26 ++++++++++++++++---------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/context.go b/context.go index cec883133b..252c53ed51 100644 --- a/context.go +++ b/context.go @@ -212,6 +212,11 @@ func (c *Ctx) DetectProjectGOPATH(p *Project) (string, error) { // detectGOPATH detects the GOPATH for a given path from ctx.GOPATHs. func (c *Ctx) detectGOPATH(path string) (string, error) { for _, gp := range c.GOPATHs { + // Evaluate symlinks in case the user's GOPATH contains a symlink. + gp, err := filepath.EvalSymlinks(gp) + if err != nil { + return "", errors.New("failed to evaluate symlinks on GOPATH") + } if fs.HasFilepathPrefix(path, gp) { return gp, nil } diff --git a/context_test.go b/context_test.go index 4ce9c0521d..bee0604b20 100644 --- a/context_test.go +++ b/context_test.go @@ -362,9 +362,11 @@ func TestDetectProjectGOPATH(t *testing.T) { h.TempDir("go") h.TempDir("go-two") + h.TempDir("go-symgopath") + h.TempSymlink("go-symgopath", "go-three") ctx := &Ctx{ - GOPATHs: []string{h.Path("go"), h.Path("go-two")}, + GOPATHs: []string{h.Path("go"), h.Path("go-two"), h.Path("go-three")}, } h.TempDir("go/src/real/path") @@ -376,12 +378,14 @@ func TestDetectProjectGOPATH(t *testing.T) { h.TempDir(filepath.Join("go", "src", "sym", "path")) h.TempDir(filepath.Join("go", "src", " real", "path")) h.TempDir(filepath.Join("go-two", "src", "real", "path")) + h.TempDir(filepath.Join("go-symgopath", "src", "real", "path")) testcases := []struct { name string root string resolvedRoot string GOPATH string + realGOPATH string expectErr bool }{ { @@ -432,6 +436,13 @@ func TestDetectProjectGOPATH(t *testing.T) { resolvedRoot: filepath.Join(ctx.GOPATHs[0], "src", " real", "path"), GOPATH: ctx.GOPATHs[0], }, + { + name: "GOPATH-is-a-symlink", + root: filepath.Join(h.Path("go-symgopath"), "src", "real", "path"), + resolvedRoot: filepath.Join(h.Path("go-symgopath"), "src", "real", "path"), + GOPATH: ctx.GOPATHs[2], + realGOPATH: h.Path("go-symgopath"), + }, } for _, tc := range testcases { @@ -447,8 +458,11 @@ func TestDetectProjectGOPATH(t *testing.T) { } else if tc.expectErr && err == nil { t.Fatalf("expected an error, got nil and gopath %s", GOPATH) } - if GOPATH != tc.GOPATH { - t.Errorf("expected GOPATH %s, got %s", tc.GOPATH, GOPATH) + if tc.realGOPATH == "" { + tc.realGOPATH = tc.GOPATH + } + if GOPATH != tc.realGOPATH { + t.Errorf("expected GOPATH %s, got %s", tc.realGOPATH, GOPATH) } }) } diff --git a/internal/test/test.go b/internal/test/test.go index c2c0faa40a..80ff1df331 100644 --- a/internal/test/test.go +++ b/internal/test/test.go @@ -497,6 +497,16 @@ func (h *Helper) TempDir(path string) { } } +// TempSymlink adds a temporary symlink for a run of testgo. +func (h *Helper) TempSymlink(old, new string) { + h.makeTempdir() + fullOldPath := filepath.Join(h.tempdir, old) + fullNewPath := filepath.Join(h.tempdir, new) + if err := os.Symlink(fullOldPath, fullNewPath); err != nil { + h.t.Fatalf("%+v", errors.Errorf("Unable to create symlink from %s -> %s", fullOldPath, fullNewPath)) + } +} + // Path returns the absolute pathname to file with the temporary // directory. func (h *Helper) Path(name string) string { @@ -504,19 +514,15 @@ func (h *Helper) Path(name string) string { h.t.Fatalf("%+v", errors.Errorf("internal testsuite error: path(%q) with no tempdir", name)) } - var joined string - if name == "." { - joined = h.tempdir - } else { - joined = filepath.Join(h.tempdir, name) + evaled, err := filepath.EvalSymlinks(h.tempdir) + if err != nil { + h.t.Fatalf("%+v", errors.Wrapf(err, "internal testsuite error: could not evaluate symlinks for dir(%q)", h.tempdir)) } - // 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)) + if name == "." { + return evaled } - return abs + return filepath.Join(evaled, name) } // MustExist fails if path does not exist.