]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/modload: more aggressive symlink analysis in FindModulePath
authorDmitry Doroginin <doroginin@gmail.com>
Fri, 13 Jul 2018 12:31:01 +0000 (12:31 +0000)
committerRuss Cox <rsc@golang.org>
Fri, 13 Jul 2018 14:16:27 +0000 (14:16 +0000)
Fixes golang/go#26217.

Change-Id: I0c456047ee31aa78b72acc413446651ca8c3882a
GitHub-Last-Rev: b700554d883b43b57c6619e31a5f8fcb22b1d71f
GitHub-Pull-Request: golang/vgo#5
Reviewed-on: https://go-review.googlesource.com/123755
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/go/internal/modload/init.go
src/cmd/go/mod_test.go

index a360a2c9edd55733f9a951ea3e9c80599f60c93c..82820899e6662c149e3cd2a45f05e0dd2dc11c34 100644 (file)
@@ -423,11 +423,23 @@ func FindModulePath(dir string) (string, error) {
        }
 
        // Look for path in GOPATH.
+       xdir, errdir := filepath.EvalSymlinks(dir)
        for _, gpdir := range filepath.SplitList(cfg.BuildContext.GOPATH) {
+               xgpdir, errgpdir := filepath.EvalSymlinks(gpdir)
                src := filepath.Join(gpdir, "src") + string(filepath.Separator)
+               xsrc := filepath.Join(xgpdir, "src") + string(filepath.Separator)
                if strings.HasPrefix(dir, src) {
                        return filepath.ToSlash(dir[len(src):]), nil
                }
+               if errdir == nil && strings.HasPrefix(xdir, src) {
+                       return filepath.ToSlash(xdir[len(src):]), nil
+               }
+               if errgpdir == nil && strings.HasPrefix(dir, xsrc) {
+                       return filepath.ToSlash(dir[len(xsrc):]), nil
+               }
+               if errdir == nil && errgpdir == nil && strings.HasPrefix(xdir, xsrc) {
+                       return filepath.ToSlash(xdir[len(xsrc):]), nil
+               }
        }
 
        // Look for .git/config with github origin as last resort.
index faebff0f7a833c3a5ebf4f8d52725d18f46abd90..4814ef82a856d57014ca1d234815893a4facddff 100644 (file)
@@ -212,6 +212,127 @@ func TestModFindModulePath(t *testing.T) {
        if path != "unexpected.com/z" || err != nil {
                t.Fatalf("FindModulePath = %q, %v, want %q, nil", path, err, "unexpected.com/z")
        }
+
+       // Empty dir outside GOPATH
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp"), 0777))
+       tg.must(os.MkdirAll(tg.path("x"), 0777))
+       cfg.BuildContext.GOPATH = tg.path("gp")
+
+       path, err = modload.FindModulePath(tg.path("x"))
+       if path != "" || err == nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, %q", path, err, "", "cannot determine module path for source directory")
+       }
+
+       // Empty dir inside GOPATH
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src/x"), 0777))
+       cfg.BuildContext.GOPATH = tg.path("gp")
+
+       path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       if !testenv.HasSymlink() {
+               t.Logf("skipping symlink tests")
+               return
+       }
+
+       // Empty dir inside GOPATH, dir has symlink
+       // GOPATH = gp
+       // gplink -> gp
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src/x"), 0777))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink")))
+       cfg.BuildContext.GOPATH = tg.path("gp")
+
+       path, err = modload.FindModulePath(tg.path("gplink/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+       path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       // Empty dir inside GOPATH, dir has symlink 2
+       // GOPATH = gp
+       // gp/src/x -> x/x
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src"), 0777))
+       tg.must(os.MkdirAll(tg.path("x/x"), 0777))
+       tg.must(os.Symlink(tg.path("x/x"), tg.path("gp/src/x")))
+       cfg.BuildContext.GOPATH = tg.path("gp")
+
+       path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       // Empty dir inside GOPATH, GOPATH has symlink
+       // GOPATH = gplink
+       // gplink -> gp
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src/x"), 0777))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink")))
+       cfg.BuildContext.GOPATH = tg.path("gplink")
+
+       path, err = modload.FindModulePath(tg.path("gplink/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+       path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       // Empty dir inside GOPATH, GOPATH has symlink, dir has symlink 2
+       // GOPATH = gplink
+       // gplink -> gp
+       // gplink2 -> gp
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src/x"), 0777))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink")))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink2")))
+       cfg.BuildContext.GOPATH = tg.path("gplink")
+
+       path, err = modload.FindModulePath(tg.path("gplink2/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+       path, err = modload.FindModulePath(tg.path("gplink/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+       path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       // Empty dir inside GOPATH, GOPATH has symlink, dir has symlink 3
+       // GOPATH = gplink
+       // gplink -> gp
+       // gplink2 -> gp
+       // gp/src/x -> x/x
+       tg.must(os.RemoveAll(tg.tempdir))
+       tg.must(os.MkdirAll(tg.path("gp/src"), 0777))
+       tg.must(os.MkdirAll(tg.path("x/x"), 0777))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink")))
+       tg.must(os.Symlink(tg.path("gp"), tg.path("gplink2")))
+       tg.must(os.Symlink(tg.path("x/x"), tg.path("gp/src/x")))
+       cfg.BuildContext.GOPATH = tg.path("gplink")
+
+       path, err = modload.FindModulePath(tg.path("gplink/src/x"))
+       if path != "x" || err != nil {
+               t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       }
+
+       // This test fails when /tmp -> /private/tmp.
+       // path, err = modload.FindModulePath(tg.path("gp/src/x"))
+       // if path != "x" || err != nil {
+       //      t.Fatalf("FindModulePath() = %q, %v, want %q, nil", path, err, "x")
+       // }
 }
 
 func TestModImportModFails(t *testing.T) {