github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/go/internal/modload/search.go (about) 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. 4 5 package modload 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "strings" 12 13 "cmd/go/internal/base" 14 "cmd/go/internal/cfg" 15 "cmd/go/internal/imports" 16 "cmd/go/internal/module" 17 "cmd/go/internal/search" 18 ) 19 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) 28 } 29 30 have := map[string]bool{ 31 "builtin": true, // ignore pseudo-package that exists only for documentation 32 } 33 if !cfg.BuildContext.CgoEnabled { 34 have["runtime/cgo"] = true // ignore during walk 35 } 36 var pkgs []string 37 38 walkPkgs := func(root, importPathRoot string) { 39 root = filepath.Clean(root) 40 var cmd string 41 if root == cfg.GOROOTsrc { 42 cmd = filepath.Join(root, "cmd") 43 } 44 filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { 45 if err != nil { 46 return nil 47 } 48 49 // Don't use GOROOT/src but do walk down into it. 50 if path == root && importPathRoot == "" { 51 return nil 52 } 53 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. 58 if path == cmd { 59 return filepath.SkipDir 60 } 61 62 want := true 63 // Avoid .foo, _foo, and testdata directory trees. 64 _, elem := filepath.Split(path) 65 if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" { 66 want = false 67 } 68 69 name := importPathRoot + filepath.ToSlash(path[len(root):]) 70 if importPathRoot == "" { 71 name = name[1:] // cut leading slash 72 } 73 if !treeCanMatch(name) { 74 want = false 75 } 76 77 if !fi.IsDir() { 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) 81 } 82 } 83 return nil 84 } 85 86 if !want { 87 return filepath.SkipDir 88 } 89 if path != root { 90 if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil { 91 return filepath.SkipDir 92 } 93 } 94 95 if !have[name] { 96 have[name] = true 97 if match(name) { 98 if _, _, err := scanDir(path, tags); err != imports.ErrNoGo { 99 pkgs = append(pkgs, name) 100 } 101 } 102 } 103 104 if elem == "vendor" { 105 return filepath.SkipDir 106 } 107 return nil 108 }) 109 } 110 111 if useStd { 112 walkPkgs(cfg.GOROOTsrc, "") 113 } 114 115 for _, mod := range modules { 116 if !treeCanMatch(mod.Path) { 117 continue 118 } 119 var root string 120 if mod.Version == "" { 121 if !HasModRoot() { 122 continue // If there is no main module, we can't search in it. 123 } 124 root = ModRoot() 125 } else { 126 var err error 127 root, _, err = fetch(mod) 128 if err != nil { 129 base.Errorf("go: %v", err) 130 continue 131 } 132 } 133 walkPkgs(root, mod.Path) 134 } 135 136 return pkgs 137 }