/
imports.go
121 lines (104 loc) · 2.18 KB
/
imports.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package tools
import (
"fmt"
"go/build"
"io/ioutil"
"path"
"strings"
)
func GetAllImportPaths() ([]string, error) {
var imports []string
for p := range parseDir(path.Join(build.Default.GOROOT, "src"), skipVendor) {
if p.err != nil {
return nil, fmt.Errorf("Error on parse dir (%s): %v", build.Default.GOROOT, p.err)
}
imports = append(imports, p.path)
}
for p := range parseDir(path.Join(build.Default.GOPATH, "src")) {
if p.err != nil {
return nil, fmt.Errorf("Error on parse dir (%s): %v", build.Default.GOPATH, p.err)
}
imports = append(imports, p.path)
}
return imports, nil
}
type importFunc func(i importPath)
type importFuncOverride func(fn importFunc) importFunc
func override(fn importFunc, fns ...importFuncOverride) importFunc {
outFn := fn
for _, f := range fns {
outFn = f(outFn)
}
return outFn
}
func skipVendor(fn importFunc) importFunc {
return func(i importPath) {
if i.isVendor {
return
}
fn(i)
}
}
type importPath struct {
path string
err error
isVendor bool
}
func parseDir(pathDir string, oo ...importFuncOverride) <-chan importPath {
out := make(chan importPath)
cropIndex := len(pathDir) + 1
sendImportFunc := override(func(i importPath) {
i.path = i.path[cropIndex:]
out <- i
}, oo...)
go func() {
err := parsingDir(pathDir, sendImportFunc)
if err != nil {
out <- importPath{err: err}
}
close(out)
}()
return out
}
func parsingDir(pathDir string, fn importFunc) error {
fs, err := ioutil.ReadDir(pathDir)
if err != nil {
return err
}
// current dir has '.go' files
var name string
for _, f := range fs {
if f.IsDir() {
continue
}
name = f.Name()
if strings.HasSuffix(name, ".go") && !strings.HasSuffix(name, "_test.go") {
fn(importPath{path: pathDir})
break
}
}
// walk dirs
for _, f := range fs {
if !f.IsDir() {
continue
}
switch f.Name() {
case "testdata", "cmd":
// skip
case "vendor":
err = parsingDir(path.Join(pathDir, f.Name()), vendor(fn))
default:
err = parsingDir(path.Join(pathDir, f.Name()), fn)
}
if err != nil {
return err
}
}
return nil
}
func vendor(fn importFunc) importFunc {
return func(i importPath) {
i.isVendor = true
fn(i)
}
}