1
2
3
4
5 package imports
6
7 import (
8 "fmt"
9 "io/fs"
10 "path/filepath"
11 "sort"
12 "strconv"
13 "strings"
14
15 "cmd/go/internal/fsys"
16 )
17
18 func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) {
19 infos, err := fsys.ReadDir(dir)
20 if err != nil {
21 return nil, nil, err
22 }
23 var files []string
24 for _, info := range infos {
25 name := info.Name()
26
27
28
29 if info.Mode()&fs.ModeSymlink != 0 {
30 info, err = fsys.Stat(filepath.Join(dir, name))
31 if err != nil {
32 continue
33 }
34 }
35
36 if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) {
37 files = append(files, filepath.Join(dir, name))
38 }
39 }
40 return scanFiles(files, tags, false)
41 }
42
43 func ScanFiles(files []string, tags map[string]bool) ([]string, []string, error) {
44 return scanFiles(files, tags, true)
45 }
46
47 func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]string, []string, error) {
48 imports := make(map[string]bool)
49 testImports := make(map[string]bool)
50 numFiles := 0
51 Files:
52 for _, name := range files {
53 r, err := fsys.Open(name)
54 if err != nil {
55 return nil, nil, err
56 }
57 var list []string
58 data, err := ReadImports(r, false, &list)
59 r.Close()
60 if err != nil {
61 return nil, nil, fmt.Errorf("reading %s: %v", name, err)
62 }
63
64
65
66
67
68
69
70 for _, path := range list {
71 if path == `"C"` && !tags["cgo"] && !tags["*"] {
72 continue Files
73 }
74 }
75
76 if !explicitFiles && !ShouldBuild(data, tags) {
77 continue
78 }
79 numFiles++
80 m := imports
81 if strings.HasSuffix(name, "_test.go") {
82 m = testImports
83 }
84 for _, p := range list {
85 q, err := strconv.Unquote(p)
86 if err != nil {
87 continue
88 }
89 m[q] = true
90 }
91 }
92 if numFiles == 0 {
93 return nil, nil, ErrNoGo
94 }
95 return keys(imports), keys(testImports), nil
96 }
97
98 var ErrNoGo = fmt.Errorf("no Go source files")
99
100 func keys(m map[string]bool) []string {
101 var list []string
102 for k := range m {
103 list = append(list, k)
104 }
105 sort.Strings(list)
106 return list
107 }
108
View as plain text