github.com/MealCraft/glide@v0.13.4/action/no_vendor.go (about) 1 package action 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 8 "github.com/Masterminds/glide/msg" 9 ) 10 11 // NoVendor generates a list of source code directories, excepting `vendor/`. 12 // 13 // If "onlyGo" is true, only folders that have Go code in them will be returned. 14 // 15 // If suffix is true, this will append `/...` to every directory. 16 func NoVendor(path string, onlyGo, suffix bool) { 17 // This is responsible for printing the results of noVend. 18 paths, err := noVend(path, onlyGo, suffix) 19 if err != nil { 20 msg.Err("Failed to walk file tree: %s", err) 21 msg.Warn("FIXME: NoVendor should exit with non-zero exit code.") 22 return 23 } 24 25 for _, p := range paths { 26 msg.Puts(p) 27 } 28 } 29 30 // noVend takes a directory and returns a list of Go-like files or directories, 31 // provided the directory is not a vendor directory. 32 // 33 // If onlyGo is true, this will filter out all directories that do not contain 34 // ".go" files. 35 // 36 // TODO: Should we move this to its own package? 37 func noVend(path string, onlyGo, suffix bool) ([]string, error) { 38 39 info, err := os.Stat(path) 40 if err != nil { 41 return []string{}, err 42 } 43 44 if !info.IsDir() { 45 return []string{path}, nil 46 } 47 48 res := []string{} 49 f, err := os.Open(path) 50 if err != nil { 51 return res, err 52 } 53 54 fis, err := f.Readdir(0) 55 if err != nil { 56 return res, err 57 } 58 59 cur := false 60 61 for _, fi := range fis { 62 if exclude(fi) { 63 continue 64 } 65 66 full := filepath.Join(path, fi.Name()) 67 if fi.IsDir() && !isVend(fi) { 68 p := "./" + full + "/..." 69 res = append(res, p) 70 } else if !fi.IsDir() && isGoish(fi) { 71 //res = append(res, full) 72 cur = true 73 } 74 } 75 76 // Filter out directories that do not contain Go code 77 if onlyGo { 78 res = hasGoSource(res, suffix) 79 } 80 81 if cur { 82 res = append(res, ".") 83 } 84 85 return res, nil 86 } 87 88 // hasGoSource returns a list of directories that contain Go source. 89 func hasGoSource(dirs []string, suffix bool) []string { 90 suf := "/" 91 if suffix { 92 suf = "/..." 93 } 94 buf := []string{} 95 for _, d := range dirs { 96 d := filepath.Dir(d) 97 found := false 98 walker := func(p string, fi os.FileInfo, err error) error { 99 // Dumb optimization 100 if found { 101 return nil 102 } 103 104 // If the file ends with .go, report a match. 105 if strings.ToLower(filepath.Ext(p)) == ".go" { 106 found = true 107 } 108 109 return nil 110 } 111 filepath.Walk(d, walker) 112 113 if found { 114 buf = append(buf, "./"+d+suf) 115 } 116 } 117 return buf 118 } 119 120 // isVend returns true of this directory is a vendor directory. 121 // 122 // TODO: Should we return true for Godeps directory? 123 func isVend(fi os.FileInfo) bool { 124 return fi.Name() == "vendor" 125 } 126 127 // exclude returns true if the directory should be excluded by Go toolchain tools. 128 // 129 // Examples: directories prefixed with '.' or '_'. 130 func exclude(fi os.FileInfo) bool { 131 if strings.HasPrefix(fi.Name(), "_") { 132 return true 133 } 134 if strings.HasPrefix(fi.Name(), ".") { 135 return true 136 } 137 return false 138 } 139 140 // isGoish returns true if the file appears to be Go source. 141 func isGoish(fi os.FileInfo) bool { 142 return filepath.Ext(fi.Name()) == ".go" 143 }