-
Notifications
You must be signed in to change notification settings - Fork 0
/
find.go
113 lines (102 loc) · 2.14 KB
/
find.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
package deplist
import (
"fmt"
"go/build"
"io/ioutil"
"path/filepath"
"sort"
"strings"
"github.com/gobuffalo/envy"
"github.com/markbates/deplist/internal/takeon/github.com/markbates/oncer"
"github.com/rogpeppe/go-internal/modfile"
)
// FindImports
func FindImports(dir string, mode build.ImportMode) ([]string, error) {
if envy.Mods() {
return viaModules(dir)
}
return viaImports(dir, mode)
}
func viaImports(dir string, mode build.ImportMode) ([]string, error) {
var err error
var names []string
cp := envy.CurrentPackage()
oncer.Do("FindImports"+dir, func() {
ctx := build.Default
if len(ctx.SrcDirs()) == 0 {
err = fmt.Errorf("no src directories found")
return
}
pkg, err := ctx.ImportDir(dir, mode)
if err != nil {
if !strings.Contains(err.Error(), "cannot find package") {
if _, ok := err.(*build.NoGoError); !ok {
return
}
}
}
if pkg.ImportPath == "." {
return
}
if pkg.Goroot {
return
}
if len(pkg.GoFiles) <= 0 {
return
}
nm := map[string]string{}
if !strings.HasPrefix(pkg.ImportPath, cp) {
nm[pkg.ImportPath] = pkg.ImportPath
}
for _, imp := range pkg.Imports {
if len(ctx.SrcDirs()) == 0 {
continue
}
d := ctx.SrcDirs()[len(ctx.SrcDirs())-1]
ip := filepath.Join(d, imp)
n, err := FindImports(ip, mode)
if err != nil {
continue
}
for _, x := range n {
nm[x] = x
}
}
var ns []string
for k := range nm {
ns = append(ns, k)
}
sort.Strings(ns)
names = ns
})
return names, err
}
func viaModules(dir string) ([]string, error) {
var names []string
p := filepath.Join(dir, "go.mod")
moddata, err := ioutil.ReadFile(p)
if err != nil {
return names, fmt.Errorf("go.mod cannot be read or does not exist while go module is enabled")
}
f, err := modfile.Parse(p, moddata, func(path, version string) (string, error) {
return version, nil
})
if err != nil {
return names, err
}
for _, r := range f.Require {
if r.Syntax == nil {
continue
}
tok := r.Syntax.Token
if len(tok) > 1 {
var ind int
if tok[0] == "require" {
ind = 1
}
names = append(names, tok[ind])
continue
}
}
return names, nil
}