diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt index ae05250c5f..948496241e 100644 --- a/src/cmd/go/testdata/script/mod_gobuild_import.txt +++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt @@ -2,49 +2,67 @@ # go/build's Import should find modules by invoking the go command -go build -o $WORK/testimport.exe ./testimport +go build -o $WORK ./testimport ./testfindonly # GO111MODULE=off env GO111MODULE=off -! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w . +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . # GO111MODULE=auto in GOPATH/src env GO111MODULE=auto -exec $WORK/testimport.exe gobuild.example.com/x/y/z/w . +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . # GO111MODULE=auto outside GOPATH/src cd $GOPATH/other env GO111MODULE=auto -exec $WORK/testimport.exe other/x/y/z/w . +exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go -! exec $WORK/testimport.exe gobuild.example.com/x/y/z/w . +! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . stderr 'cannot find module providing package gobuild.example.com/x/y/z/w' cd z -exec $WORK/testimport.exe other/x/y/z/w . +exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go # GO111MODULE=on outside GOPATH/src env GO111MODULE= -exec $WORK/testimport.exe other/x/y/z/w . +exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go env GO111MODULE=on -exec $WORK/testimport.exe other/x/y/z/w . +exec $WORK/testimport$GOEXE other/x/y/z/w . stdout w2.go # GO111MODULE=on in GOPATH/src cd $GOPATH/src env GO111MODULE= -exec $WORK/testimport.exe gobuild.example.com/x/y/z/w . +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . stdout w1.go env GO111MODULE=on -exec $WORK/testimport.exe gobuild.example.com/x/y/z/w . +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w . stdout w1.go cd w -exec $WORK/testimport.exe gobuild.example.com/x/y/z/w .. +exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .. stdout w1.go +# go/build's Import in FindOnly mode should find directories by invoking the go command +# +# Calling build.Import in build.FindOnly mode on an import path of a Go package +# that produces errors when loading (e.g., due to build constraints not matching +# the current build context) should return the package directory and nil error. + +# Issue 31603: Import with non-empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i $WORK +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=$' + +# Issue 37153: Import with empty srcDir should work. +env GO111MODULE=on +exec $WORK/testfindonly$GOEXE gobuild.example.com/x/y/z/i '' +! stdout 'build constraints' +stdout '^dir=\$WORK.+i err=$' + -- go.mod -- module gobuild.example.com/x/y/z @@ -54,6 +72,11 @@ package z -- w/w1.go -- package w +-- i/i.go -- +// +build i + +package i + -- testimport/x.go -- package main @@ -89,6 +112,20 @@ func main() { fmt.Printf("%s\n%s\n", p1.Dir, strings.Join(p1.GoFiles, " ")) } +-- testfindonly/x.go -- +package main + +import ( + "fmt" + "go/build" + "os" +) + +func main() { + p, err := build.Import(os.Args[1], os.Args[2], build.FindOnly) + fmt.Printf("dir=%s err=%v\n", p.Dir, err) +} + -- $GOPATH/other/go.mod -- module other/x/y diff --git a/src/go/build/build.go b/src/go/build/build.go index e89aa7708d..1a122c615f 100644 --- a/src/go/build/build.go +++ b/src/go/build/build.go @@ -1015,8 +1015,6 @@ var errNoModules = errors.New("not using modules") // Then we reinvoke it for every dependency. But this is still better than not working at all. // See golang.org/issue/26504. func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error { - const debugImportGo = false - // To invoke the go command, // we must not being doing special things like AllowBinary or IgnoreVendor, // and all the file system callbacks must be nil (we're meant to use the local file system). @@ -1135,15 +1133,15 @@ func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) } dir := f[0] errStr := strings.TrimSpace(f[4]) - if errStr != "" && p.Dir == "" { - // If 'go list' could not locate the package, return the same error that - // 'go list' reported. - // If 'go list' did locate the package (p.Dir is not empty), ignore the - // error. It was probably related to loading source files, and we'll - // encounter it ourselves shortly. + if errStr != "" && dir == "" { + // If 'go list' could not locate the package (dir is empty), + // return the same error that 'go list' reported. return errors.New(errStr) } + // If 'go list' did locate the package, ignore the error. + // It was probably related to loading source files, and we'll + // encounter it ourselves shortly if the FindOnly flag isn't set. p.Dir = dir p.ImportPath = f[1] p.Root = f[2]