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  }