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