forked from Masterminds/glide
-
Notifications
You must be signed in to change notification settings - Fork 0
/
no_vendor.go
143 lines (121 loc) · 2.93 KB
/
no_vendor.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package action
import (
"os"
"path/filepath"
"strings"
"github.com/Masterminds/glide/msg"
)
// NoVendor generates a list of source code directories, excepting `vendor/`.
//
// If "onlyGo" is true, only folders that have Go code in them will be returned.
//
// If suffix is true, this will append `/...` to every directory.
func NoVendor(path string, onlyGo, suffix bool) {
// This is responsible for printing the results of noVend.
paths, err := noVend(path, onlyGo, suffix)
if err != nil {
msg.Err("Failed to walk file tree: %s", err)
msg.Warn("FIXME: NoVendor should exit with non-zero exit code.")
return
}
for _, p := range paths {
msg.Puts(p)
}
}
// noVend takes a directory and returns a list of Go-like files or directories,
// provided the directory is not a vendor directory.
//
// If onlyGo is true, this will filter out all directories that do not contain
// ".go" files.
//
// TODO: Should we move this to its own package?
func noVend(path string, onlyGo, suffix bool) ([]string, error) {
info, err := os.Stat(path)
if err != nil {
return []string{}, err
}
if !info.IsDir() {
return []string{path}, nil
}
res := []string{}
f, err := os.Open(path)
if err != nil {
return res, err
}
fis, err := f.Readdir(0)
if err != nil {
return res, err
}
cur := false
for _, fi := range fis {
if exclude(fi) {
continue
}
full := filepath.Join(path, fi.Name())
if fi.IsDir() && !isVend(fi) {
p := "./" + full + "/..."
res = append(res, p)
} else if !fi.IsDir() && isGoish(fi) {
//res = append(res, full)
cur = true
}
}
// Filter out directories that do not contain Go code
if onlyGo {
res = hasGoSource(res, suffix)
}
if cur {
res = append(res, ".")
}
return res, nil
}
// hasGoSource returns a list of directories that contain Go source.
func hasGoSource(dirs []string, suffix bool) []string {
suf := "/"
if suffix {
suf = "/..."
}
buf := []string{}
for _, d := range dirs {
d := filepath.Dir(d)
found := false
walker := func(p string, fi os.FileInfo, err error) error {
// Dumb optimization
if found {
return nil
}
// If the file ends with .go, report a match.
if strings.ToLower(filepath.Ext(p)) == ".go" {
found = true
}
return nil
}
filepath.Walk(d, walker)
if found {
buf = append(buf, "./"+d+suf)
}
}
return buf
}
// isVend returns true of this directory is a vendor directory.
//
// TODO: Should we return true for Godeps directory?
func isVend(fi os.FileInfo) bool {
return fi.Name() == "vendor"
}
// exclude returns true if the directory should be excluded by Go toolchain tools.
//
// Examples: directories prefixed with '.' or '_'.
func exclude(fi os.FileInfo) bool {
if strings.HasPrefix(fi.Name(), "_") {
return true
}
if strings.HasPrefix(fi.Name(), ".") {
return true
}
return false
}
// isGoish returns true if the file appears to be Go source.
func isGoish(fi os.FileInfo) bool {
return filepath.Ext(fi.Name()) == ".go"
}