github.com/Benchkram/bob@v0.0.0-20220321080157-7c8f3876e225/bobgit/bobgit.go (about) 1 package bobgit 2 3 import ( 4 "fmt" 5 "io/fs" 6 "os" 7 "path/filepath" 8 9 "github.com/Benchkram/errz" 10 ) 11 12 var ( 13 ErrOutsideBobWorkspace = fmt.Errorf("Not allowed, path pointing outside of Bob workspace.") 14 ErrCouldNotFindGitDir = fmt.Errorf("Could not find a .git folder") 15 ) 16 17 var dontFollow = []string{ 18 "node_modules", 19 ".git", 20 ".vscode", 21 } 22 23 // isGitRepo return true is the directory contains a `.git` directory 24 func isGitRepo(dir string) (isGit bool, err error) { 25 defer errz.Recover(&err) 26 entrys, err := os.ReadDir(dir) 27 errz.Fatal(err) 28 29 for _, entry := range entrys { 30 if !entry.IsDir() { 31 continue 32 } 33 34 if entry.Name() == ".git" { 35 isGit = true 36 break 37 } 38 } 39 40 return isGit, nil 41 } 42 43 // findRepos searches for git repos inside provided root directory 44 func findRepos(root string) ([]string, error) { 45 repoNames := []string{} 46 err := filepath.WalkDir(root, func(path string, d fs.DirEntry, err error) error { 47 if !d.IsDir() { 48 return nil 49 } 50 51 if d.Name() == ".git" { 52 p, err := filepath.Rel(root, filepath.Dir(path)) 53 if err != nil { 54 return err 55 } 56 repoNames = append(repoNames, p) 57 } 58 59 for _, dir := range dontFollow { 60 if d.Name() == dir { 61 return fs.SkipDir 62 } 63 } 64 65 return nil 66 }) 67 68 if err != nil { 69 return repoNames, err 70 } 71 72 return repoNames, nil 73 } 74 75 // formatRepoNameForOutput returns formatted reponame for output. 76 // 77 // Example: "." => "/", "second-level" => "second-level/" 78 func formatRepoNameForOutput(reponame string) string { 79 repopath := reponame 80 if reponame == "." { 81 repopath = "/" 82 } else if repopath[len(repopath)-1:] != "/" { 83 repopath = repopath + "/" 84 } 85 return repopath 86 }