-
Notifications
You must be signed in to change notification settings - Fork 14
/
m_import_paths.go
116 lines (105 loc) · 2.22 KB
/
m_import_paths.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
package main
import (
"go/ast"
"go/parser"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)
type mImportPaths struct {
Fn string
Src string
Env map[string]string
}
type mImportPathsDecl struct {
Name string `json:"name"`
Path string `json:"path"`
}
func (m *mImportPaths) Call() (interface{}, string) {
imports := []mImportPathsDecl{}
_, af, err := parseAstFile(m.Fn, m.Src, parser.ImportsOnly)
if err != nil {
return M{}, err.Error()
}
if m.Fn != "" || m.Src != "" {
for _, decl := range af.Decls {
if gdecl, ok := decl.(*ast.GenDecl); ok && len(gdecl.Specs) > 0 {
for _, spec := range gdecl.Specs {
if ispec, ok := spec.(*ast.ImportSpec); ok {
sd := mImportPathsDecl{
Path: unquote(ispec.Path.Value),
}
if ispec.Name != nil {
sd.Name = ispec.Name.String()
}
imports = append(imports, sd)
}
}
}
}
}
paths := map[string]string{}
l, _ := importPaths(m.Env)
for _, p := range l {
paths[p] = ""
}
res := M{
"imports": imports,
"paths": paths,
}
return res, ""
}
func init() {
registry.Register("import_paths", func(_ *Broker) Caller {
return &mImportPaths{
Env: map[string]string{},
}
})
}
func importPaths(environ map[string]string) ([]string, error) {
imports := []string{
"unsafe",
}
paths := map[string]bool{}
env := []string{
environ["GOPATH"],
environ["GOROOT"],
os.Getenv("GOPATH"),
os.Getenv("GOROOT"),
runtime.GOROOT(),
}
for _, ent := range env {
for _, path := range filepath.SplitList(ent) {
if path != "" {
paths[path] = true
}
}
}
seen := map[string]bool{}
pfx := strings.HasPrefix
sfx := strings.HasSuffix
osArch := runtime.GOOS + "_" + runtime.GOARCH
for root, _ := range paths {
root = filepath.Join(root, "pkg", osArch)
walkF := func(p string, info os.FileInfo, err error) error {
if err == nil && !info.IsDir() {
p, e := filepath.Rel(root, p)
if e == nil && sfx(p, ".a") {
p := p[:len(p)-2]
if !pfx(p, ".") && !pfx(p, "_") && !sfx(p, "_test") {
p = path.Clean(filepath.ToSlash(p))
if !seen[p] {
seen[p] = true
imports = append(imports, p)
}
}
}
}
return nil
}
filepath.Walk(root, walkF)
}
return imports, nil
}