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