]> Cypherpunks repositories - gostls13.git/commitdiff
go/build: don't check if srcDir in GOPATH when deciding to use modules
authorJay Conrod <jayconrod@google.com>
Thu, 27 Jun 2019 19:28:08 +0000 (15:28 -0400)
committerJay Conrod <jayconrod@google.com>
Thu, 27 Jun 2019 19:58:49 +0000 (19:58 +0000)
go/build.Context.Import loads package information using 'go list' when
in module mode. It does this when GO111MODULE is not "off", there is a
go.mod file in any parent directory, and neither the path nor the
source directory are in GOROOT. Import no longer checks whether the
source directory is in GOPATH if GO111MODULE=auto or unset.

Also fixed subdirectory checks that did not handle relative source
directory paths. mod_gobuild_import should have failed when we changed
the meaning of GO111MODULE=auto but didn't because of this.

Fixes #32799

Change-Id: Ic5210b7e00cb58f91ea9455b67b49d5aed4eec63
Reviewed-on: https://go-review.googlesource.com/c/go/+/184098
Run-TryBot: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/go/testdata/script/mod_gobuild_import.txt
src/go/build/build.go

index a4eb5d6596f49f50a5f87dbd949d68bfc05bae84..ae05250c5f695bfe80e914d0994cf319ad6dacc4 100644 (file)
@@ -62,15 +62,31 @@ import (
        "go/build"
        "log"
        "os"
+       "path/filepath"
        "strings"
 )
 
 func main() {
-       p, err := build.Import(os.Args[1], os.Args[2], 0)
+       // build.Import should support relative and absolute source dir paths.
+       path := os.Args[1]
+       srcDir := os.Args[2]
+       p1, err := build.Import(path, srcDir, 0)
        if err != nil {
                log.Fatal(err)
        }
-       fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " "))
+       absSrcDir, err := filepath.Abs(srcDir)
+       if err != nil {
+               log.Fatal(err)
+       }
+       p2, err := build.Import(path, absSrcDir, 0)
+       if err != nil {
+               log.Fatal(err)
+       }
+       if p1.Dir != p2.Dir {
+               log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir)
+       }
+
+       fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " "))
 }
 
 -- $GOPATH/other/go.mod --
index a91551bc22c15687fc3d5a5d7b1f67bb86d9e441..f8547606aad05396213fabc3fdc4dcb52d7b9291 100644 (file)
@@ -1001,27 +1001,25 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode,
                return errNoModules
        }
 
+       // Find the absolute source directory. hasSubdir does not handle
+       // relative paths (and can't because the callbacks don't support this).
+       absSrcDir, err := filepath.Abs(srcDir)
+       if err != nil {
+               return errNoModules
+       }
+
        // If modules are not enabled, then the in-process code works fine and we should keep using it.
-       // TODO(bcmills): This assumes that the default is "auto" instead of "on".
        switch os.Getenv("GO111MODULE") {
        case "off":
                return errNoModules
-       case "on":
-               // ok
-       default: // "", "auto", anything else
-               // Automatic mode: no module use in $GOPATH/src.
-               for _, root := range gopath {
-                       sub, ok := ctxt.hasSubdir(root, srcDir)
-                       if ok && strings.HasPrefix(sub, "src/") {
-                               return errNoModules
-                       }
-               }
+       default: // "", "on", "auto", anything else
+               // Maybe use modules.
        }
 
        // If the source directory is in GOROOT, then the in-process code works fine
        // and we should keep using it. Moreover, the 'go list' approach below doesn't
        // take standard-library vendoring into account and will fail.
-       if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), srcDir); ok {
+       if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok {
                return errNoModules
        }
 
@@ -1034,20 +1032,18 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode,
        }
 
        // Look to see if there is a go.mod.
-       abs, err := filepath.Abs(srcDir)
-       if err != nil {
-               return errNoModules
-       }
+       // Since go1.13, it doesn't matter if we're inside GOPATH.
+       parent := absSrcDir
        for {
-               info, err := os.Stat(filepath.Join(abs, "go.mod"))
+               info, err := os.Stat(filepath.Join(parent, "go.mod"))
                if err == nil && !info.IsDir() {
                        break
                }
-               d := filepath.Dir(abs)
-               if len(d) >= len(abs) {
+               d := filepath.Dir(parent)
+               if len(d) >= len(parent) {
                        return errNoModules // reached top of file system, no go.mod
                }
-               abs = d
+               parent = d
        }
 
        cmd := exec.Command("go", "list", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n", path)