package main import ( "flag" "fmt" "log" "os" "path/filepath" "strings" "github.com/go-git/go-git/v5" ) const ( defaultDir = "." green = "\033[32m" red = "\033[31m" reset = "\033[0m" ) func main() { flag.Parse() args := flag.Args() dir := defaultDir if len(args) > 0 { dir = args[0] } path, err := expandTilde(dir) if err != nil { log.Fatal(err) } entries, err := os.ReadDir(path) if err != nil { log.Fatal(err) } for _, d := range entries { cpath := filepath.Join(path, d.Name()) status, err := getStatus(cpath) if err != nil { fmt.Println(cpath) continue } if !status.IsClean() { fmt.Printf("%s%s (%v)%s\n", green, cpath, len(status), reset) } else { fmt.Println(cpath) } } } func getStatus(repoPath string) (git.Status, error) { repo, err := git.PlainOpen(repoPath) if err != nil { return git.Status{}, err } w, err := repo.Worktree() if err != nil { return git.Status{}, err } status, err := w.Status() if err != nil { return git.Status{}, err } return status, nil } func expandTilde(path string) (string, error) { if !strings.HasPrefix(path, "~") { return path, nil } home, err := os.UserHomeDir() if err != nil { return "", err } return filepath.Join(home, path[1:]), nil }