| 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" |
| } |