Skip to content

Commit f1a8ca3

Browse files
author
Jay Conrod
committed
go/build: don't check if srcDir in GOPATH when deciding to use modules
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 <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 0d4de70 commit f1a8ca3

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

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

+18-2
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,31 @@ import (
6262
"go/build"
6363
"log"
6464
"os"
65+
"path/filepath"
6566
"strings"
6667
)
6768

6869
func main() {
69-
p, err := build.Import(os.Args[1], os.Args[2], 0)
70+
// build.Import should support relative and absolute source dir paths.
71+
path := os.Args[1]
72+
srcDir := os.Args[2]
73+
p1, err := build.Import(path, srcDir, 0)
7074
if err != nil {
7175
log.Fatal(err)
7276
}
73-
fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " "))
77+
absSrcDir, err := filepath.Abs(srcDir)
78+
if err != nil {
79+
log.Fatal(err)
80+
}
81+
p2, err := build.Import(path, absSrcDir, 0)
82+
if err != nil {
83+
log.Fatal(err)
84+
}
85+
if p1.Dir != p2.Dir {
86+
log.Fatalf("different packages loaded with relative and absolute paths:\n\t%s\n\t%s", p1.Dir, p2.Dir)
87+
}
88+
89+
fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " "))
7490
}
7591

7692
-- $GOPATH/other/go.mod --

src/go/build/build.go

+16-20
Original file line numberDiff line numberDiff line change
@@ -1001,27 +1001,25 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode,
10011001
return errNoModules
10021002
}
10031003

1004+
// Find the absolute source directory. hasSubdir does not handle
1005+
// relative paths (and can't because the callbacks don't support this).
1006+
absSrcDir, err := filepath.Abs(srcDir)
1007+
if err != nil {
1008+
return errNoModules
1009+
}
1010+
10041011
// If modules are not enabled, then the in-process code works fine and we should keep using it.
1005-
// TODO(bcmills): This assumes that the default is "auto" instead of "on".
10061012
switch os.Getenv("GO111MODULE") {
10071013
case "off":
10081014
return errNoModules
1009-
case "on":
1010-
// ok
1011-
default: // "", "auto", anything else
1012-
// Automatic mode: no module use in $GOPATH/src.
1013-
for _, root := range gopath {
1014-
sub, ok := ctxt.hasSubdir(root, srcDir)
1015-
if ok && strings.HasPrefix(sub, "src/") {
1016-
return errNoModules
1017-
}
1018-
}
1015+
default: // "", "on", "auto", anything else
1016+
// Maybe use modules.
10191017
}
10201018

10211019
// If the source directory is in GOROOT, then the in-process code works fine
10221020
// and we should keep using it. Moreover, the 'go list' approach below doesn't
10231021
// take standard-library vendoring into account and will fail.
1024-
if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), srcDir); ok {
1022+
if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok {
10251023
return errNoModules
10261024
}
10271025

@@ -1034,20 +1032,18 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode,
10341032
}
10351033

10361034
// Look to see if there is a go.mod.
1037-
abs, err := filepath.Abs(srcDir)
1038-
if err != nil {
1039-
return errNoModules
1040-
}
1035+
// Since go1.13, it doesn't matter if we're inside GOPATH.
1036+
parent := absSrcDir
10411037
for {
1042-
info, err := os.Stat(filepath.Join(abs, "go.mod"))
1038+
info, err := os.Stat(filepath.Join(parent, "go.mod"))
10431039
if err == nil && !info.IsDir() {
10441040
break
10451041
}
1046-
d := filepath.Dir(abs)
1047-
if len(d) >= len(abs) {
1042+
d := filepath.Dir(parent)
1043+
if len(d) >= len(parent) {
10481044
return errNoModules // reached top of file system, no go.mod
10491045
}
1050-
abs = d
1046+
parent = d
10511047
}
10521048

10531049
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)

0 commit comments

Comments
 (0)