Skip to content

Commit 514c559

Browse files
author
Bryan C. Mills
committed
go/build: change the search order for "vendor/" paths based on srcDir
If srcDir is within GOROOT, prefer GOROOT. Otherwise, prefer GOPATH. The attached tests may seem a bit strange; they will make more sense in a followup CL. Updates #16333 Updates #30241 Updates #30228 Change-Id: Ic5f1334cce5e242d7f49080aba083bcf2080dee3 Reviewed-on: https://go-review.googlesource.com/c/go/+/164619 Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jay Conrod <[email protected]>
1 parent 10156b6 commit 514c559

File tree

2 files changed

+79
-10
lines changed

2 files changed

+79
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
env GO111MODULE=off
2+
3+
[!gc] skip
4+
5+
# A package importing 'net/http' should resolve its dependencies
6+
# to the package 'vendor/golang.org/x/net/http2/hpack' within GOROOT.
7+
cd importnethttp
8+
go list -deps -f '{{.ImportPath}} {{.Dir}}'
9+
stdout ^internal/x/net/http2/hpack
10+
stdout $GOROOT[/\\]src[/\\]internal[/\\]x[/\\]net[/\\]http2[/\\]hpack
11+
! stdout $GOPATH[/\\]src[/\\]vendor
12+
13+
# In the presence of $GOPATH/src/vendor/golang.org/x/net/http2/hpack,
14+
# a package in GOPATH importing 'golang.org/x/net/http2/hpack' should
15+
# resolve its dependencies in GOPATH/src.
16+
cd ../issue16333
17+
go build .
18+
19+
go list -deps -f '{{.ImportPath}} {{.Dir}}' .
20+
stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack
21+
! stdout $GOROOT[/\\]src[/\\]vendor
22+
23+
go list -test -deps -f '{{.ImportPath}} {{.Dir}}' .
24+
stdout $GOPATH[/\\]src[/\\]vendor[/\\]golang.org[/\\]x[/\\]net[/\\]http2[/\\]hpack
25+
! stdout $GOROOT[/\\]src[/\\]vendor
26+
27+
-- issue16333/issue16333.go --
28+
package vendoring17
29+
30+
import _ "golang.org/x/net/http2/hpack"
31+
-- issue16333/issue16333_test.go --
32+
package vendoring17
33+
34+
import _ "testing"
35+
import _ "golang.org/x/net/http2/hpack"
36+
-- importnethttp/http.go --
37+
package importnethttp
38+
39+
import _ "net/http"
40+
-- $GOPATH/src/vendor/golang.org/x/net/http2/hpack/hpack.go --
41+
package hpack

src/go/build/build.go

+38-10
Original file line numberDiff line numberDiff line change
@@ -647,18 +647,28 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
647647

648648
// Determine directory from import path.
649649
if ctxt.GOROOT != "" {
650-
dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
651-
if ctxt.Compiler != "gccgo" {
652-
isDir := ctxt.isDir(dir)
653-
binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
654-
if isDir || binaryOnly {
655-
p.Dir = dir
656-
p.Goroot = true
657-
p.Root = ctxt.GOROOT
658-
goto Found
650+
// If the package path starts with "vendor/", only search GOROOT before
651+
// GOPATH if the importer is also within GOROOT. That way, if the user has
652+
// vendored in a package that is subsequently included in the standard
653+
// distribution, they'll continue to pick up their own vendored copy.
654+
gorootFirst := srcDir == "" || !strings.HasPrefix(path, "vendor/")
655+
if !gorootFirst {
656+
_, gorootFirst = ctxt.hasSubdir(ctxt.GOROOT, srcDir)
657+
}
658+
if gorootFirst {
659+
dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
660+
if ctxt.Compiler != "gccgo" {
661+
isDir := ctxt.isDir(dir)
662+
binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
663+
if isDir || binaryOnly {
664+
p.Dir = dir
665+
p.Goroot = true
666+
p.Root = ctxt.GOROOT
667+
goto Found
668+
}
659669
}
670+
tried.goroot = dir
660671
}
661-
tried.goroot = dir
662672
}
663673
if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
664674
p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
@@ -678,6 +688,24 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
678688
tried.gopath = append(tried.gopath, dir)
679689
}
680690

691+
// If we tried GOPATH first due to a "vendor/" prefix, fall back to GOPATH.
692+
// That way, the user can still get useful results from 'go list' for
693+
// standard-vendored paths passed on the command line.
694+
if ctxt.GOROOT != "" && tried.goroot == "" {
695+
dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
696+
if ctxt.Compiler != "gccgo" {
697+
isDir := ctxt.isDir(dir)
698+
binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
699+
if isDir || binaryOnly {
700+
p.Dir = dir
701+
p.Goroot = true
702+
p.Root = ctxt.GOROOT
703+
goto Found
704+
}
705+
}
706+
tried.goroot = dir
707+
}
708+
681709
// package was not found
682710
var paths []string
683711
format := "\t%s (vendor tree)"

0 commit comments

Comments
 (0)