1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 "cmd/go/internal/base"
15 "cmd/go/internal/imports"
16 "cmd/go/internal/module"
17 "cmd/go/internal/search"
20 // matchPackages returns a list of packages in the list of modules
21 // matching the pattern. Package loading assumes the given set of tags.
22 func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []module.Version) []string {
23 match := func(string) bool { return true }
24 treeCanMatch := func(string) bool { return true }
25 if !search.IsMetaPackage(pattern) {
26 match = search.MatchPattern(pattern)
27 treeCanMatch = search.TreeCanMatchPattern(pattern)
30 have := map[string]bool{
31 "builtin": true, // ignore pseudo-package that exists only for documentation
33 if !cfg.BuildContext.CgoEnabled {
34 have["runtime/cgo"] = true // ignore during walk
38 walkPkgs := func(root, importPathRoot string) {
39 root = filepath.Clean(root)
41 if root == cfg.GOROOTsrc {
42 cmd = filepath.Join(root, "cmd")
44 filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
49 // Don't use GOROOT/src but do walk down into it.
50 if path == root && importPathRoot == "" {
54 // GOROOT/src/cmd makes use of GOROOT/src/cmd/vendor,
55 // which module mode can't deal with. Eventually we'll stop using
56 // that vendor directory, and then we can remove this exclusion.
57 // golang.org/issue/26924.
59 return filepath.SkipDir
63 // Avoid .foo, _foo, and testdata directory trees.
64 _, elem := filepath.Split(path)
65 if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
69 name := importPathRoot + filepath.ToSlash(path[len(root):])
70 if importPathRoot == "" {
71 name = name[1:] // cut leading slash
73 if !treeCanMatch(name) {
78 if fi.Mode()&os.ModeSymlink != 0 && want {
79 if target, err := os.Stat(path); err == nil && target.IsDir() {
80 fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path)
87 return filepath.SkipDir
90 if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil {
91 return filepath.SkipDir
98 if _, _, err := scanDir(path, tags); err != imports.ErrNoGo {
99 pkgs = append(pkgs, name)
104 if elem == "vendor" {
105 return filepath.SkipDir
112 walkPkgs(cfg.GOROOTsrc, "")
115 for _, mod := range modules {
116 if !treeCanMatch(mod.Path) {
120 if mod.Version == "" {
124 root, _, err = fetch(mod)
126 base.Errorf("go: %v", err)
130 walkPkgs(root, mod.Path)