blob: 961d9924c5a1e5ac238c465d1290785325ef1578 [file] [log] [blame]
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"
}