aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/modload/search.go
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2019-04-19 12:27:25 -0400
committerBryan C. Mills <bcmills@google.com>2019-04-19 18:37:41 +0000
commit14b5b4a2a13c3148fdfeb4852436661791a13e2e (patch)
tree6337a69616340a63aa76011cb47603fbe61c42cb /src/cmd/go/internal/modload/search.go
parentdbe32284ff4fb96906cdb121508eba668dbc5bae (diff)
downloadgo-14b5b4a2a13c3148fdfeb4852436661791a13e2e.tar.gz
go-14b5b4a2a13c3148fdfeb4852436661791a13e2e.zip
cmd/go/internal/modload: fix boundary conditions in matchPackages
This makes the boundary logic of matchPackages consistent with modload.dirInModule. Previously, matchPackages always stopped at go.mod file, even within the vendor tree. However, we do not guarantee that the vendor tree is free of such files in general. matchPackages also issued needless stat operations for modules in the module cach, which we already know to be free of nested modules. On systems with slow filesystems (such as macOS), those extra calls could potentially slow package matching considerably. Change-Id: I71979ab752e1d3971b370b37085d30502690413b Reviewed-on: https://go-review.googlesource.com/c/go/+/172985 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src/cmd/go/internal/modload/search.go')
-rw-r--r--src/cmd/go/internal/modload/search.go36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/cmd/go/internal/modload/search.go b/src/cmd/go/internal/modload/search.go
index 3af39747c6..d82386eca3 100644
--- a/src/cmd/go/internal/modload/search.go
+++ b/src/cmd/go/internal/modload/search.go
@@ -35,7 +35,13 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []
}
var pkgs []string
- walkPkgs := func(root, importPathRoot string, includeVendor bool) {
+ type pruning int8
+ const (
+ pruneVendor = pruning(1 << iota)
+ pruneGoMod
+ )
+
+ walkPkgs := func(root, importPathRoot string, prune pruning) {
root = filepath.Clean(root)
filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
if err != nil {
@@ -75,7 +81,7 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []
return filepath.SkipDir
}
// Stop at module boundaries.
- if path != root {
+ if (prune&pruneGoMod != 0) && path != root {
if fi, err := os.Stat(filepath.Join(path, "go.mod")); err == nil && !fi.IsDir() {
return filepath.SkipDir
}
@@ -90,7 +96,7 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []
}
}
- if elem == "vendor" && !includeVendor {
+ if elem == "vendor" && (prune&pruneVendor != 0) {
return filepath.SkipDir
}
return nil
@@ -98,16 +104,16 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []
}
if useStd {
- walkPkgs(cfg.GOROOTsrc, "", true)
+ walkPkgs(cfg.GOROOTsrc, "", pruneGoMod)
if treeCanMatch("cmd") {
- walkPkgs(filepath.Join(cfg.GOROOTsrc, "cmd"), "cmd", true)
+ walkPkgs(filepath.Join(cfg.GOROOTsrc, "cmd"), "cmd", pruneGoMod)
}
}
if cfg.BuildMod == "vendor" {
if HasModRoot() {
- walkPkgs(ModRoot(), targetPrefix, false)
- walkPkgs(filepath.Join(ModRoot(), "vendor"), "", false)
+ walkPkgs(ModRoot(), targetPrefix, pruneGoMod|pruneVendor)
+ walkPkgs(filepath.Join(ModRoot(), "vendor"), "", pruneVendor)
}
return pkgs
}
@@ -116,23 +122,33 @@ func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []
if !treeCanMatch(mod.Path) {
continue
}
- var root, modPrefix string
+
+ var (
+ root, modPrefix string
+ isLocal bool
+ )
if mod == Target {
if !HasModRoot() {
continue // If there is no main module, we can't search in it.
}
root = ModRoot()
modPrefix = targetPrefix
+ isLocal = true
} else {
var err error
- root, _, err = fetch(mod)
+ root, isLocal, err = fetch(mod)
if err != nil {
base.Errorf("go: %v", err)
continue
}
modPrefix = mod.Path
}
- walkPkgs(root, modPrefix, false)
+
+ prune := pruneVendor
+ if isLocal {
+ prune |= pruneGoMod
+ }
+ walkPkgs(root, modPrefix, prune)
}
return pkgs