github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/pkg/filepathutil/list.go (about) 1 package filepathutil 2 3 import ( 4 "fmt" 5 "io/fs" 6 "os" 7 "path/filepath" 8 9 "github.com/yargevad/filepathx" 10 ) 11 12 // DefaultIgnores 13 var ( 14 DefaultIgnores = map[string]bool{ 15 "node_modules": true, 16 ".git": true, 17 } 18 ) 19 20 func ListRecursive(inp string) (all []string, err error) { 21 22 // TODO: possibly ignore here too, before calling listDir 23 if s, err := os.Stat(inp); err != nil || !s.IsDir() { 24 // File 25 26 // Use glob for unknowns (wildcard-paths) and existing files (non-dirs) 27 matches, err := filepathx.Glob(inp) 28 if err != nil { 29 return nil, fmt.Errorf("failed to glob %q: %w", inp, err) 30 } 31 32 for _, m := range matches { 33 s, err := os.Stat(m) 34 if err == nil && !s.IsDir() { 35 36 // Existing file 37 all = append(all, m) 38 } else { 39 // Directory 40 files, err := listDir(m) 41 if err != nil { 42 // TODO: handle error 43 return nil, fmt.Errorf("failed to list dir: %w", err) 44 } 45 46 all = append(all, files...) 47 } 48 } 49 } else { 50 // Directory 51 files, err := listDir(inp) 52 if err != nil { 53 return nil, fmt.Errorf("failed to list dir: %w", err) 54 } 55 56 all = append(all, files...) 57 } 58 59 return all, nil 60 } 61 62 var WalkedDirs = map[string]int{} 63 64 func listDir(path string) ([]string, error) { 65 66 times := WalkedDirs[path] 67 WalkedDirs[path] = times + 1 68 69 var all []string 70 if err := filepath.WalkDir(path, func(p string, fi fs.DirEntry, err error) error { 71 if err != nil { 72 return err 73 } 74 75 // Skip default ignored 76 if fi.IsDir() && ignored(fi.Name()) { 77 return fs.SkipDir 78 } 79 80 // Skip dirs 81 if !fi.IsDir() { 82 all = append(all, p) 83 } 84 85 return nil 86 }); err != nil { 87 return nil, fmt.Errorf("failed to walk dir %q: %w", path, err) 88 } 89 90 return all, nil 91 } 92 93 func ignored(fileName string) bool { 94 return DefaultIgnores[fileName] 95 }