github.com/emmahsax/go-git-helper@v0.0.8-0.20240519163017-907b9de0fa52/internal/git/git.go (about)

     1  package git
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"github.com/emmahsax/go-git-helper/internal/executor"
    10  	"github.com/emmahsax/go-git-helper/internal/utils"
    11  )
    12  
    13  type Git struct {
    14  	Debug    bool
    15  	Executor executor.ExecutorInterface
    16  }
    17  
    18  func NewGit(debug bool, executor executor.ExecutorInterface) *Git {
    19  	return &Git{
    20  		Debug:    debug,
    21  		Executor: executor,
    22  	}
    23  }
    24  
    25  func (g *Git) Checkout(branch string) {
    26  	_, err := g.Executor.Exec("waitAndStdout", "git", "checkout", branch)
    27  	if err != nil {
    28  		utils.HandleError(err, g.Debug, nil)
    29  		return
    30  	}
    31  }
    32  
    33  func (g *Git) CleanDeletedBranches() {
    34  	output, err := g.Executor.Exec("actionAndOutput", "git", "branch", "-vv")
    35  	if err != nil {
    36  		utils.HandleError(err, g.Debug, nil)
    37  		return
    38  	}
    39  
    40  	branches := strings.Split(string(output), "\n")
    41  	pattern := "origin/.*: gone"
    42  
    43  	for _, branch := range branches {
    44  		re := regexp.MustCompile(pattern)
    45  
    46  		if re.MatchString(branch) {
    47  			b := strings.Fields(branch)[0]
    48  			output, err = g.Executor.Exec("actionAndOutput", "git", "branch", "-D", b)
    49  			if err != nil {
    50  				utils.HandleError(err, g.Debug, nil)
    51  				return
    52  			}
    53  
    54  			fmt.Printf("%s", string(output))
    55  		}
    56  	}
    57  }
    58  
    59  func (g *Git) CreateBranch(branch string) error {
    60  	_, err := g.Executor.Exec("waitAndStdout", "git", "branch", "--no-track", branch)
    61  	if err != nil {
    62  		return err
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  func (g *Git) CreateEmptyCommit() {
    69  	_, err := g.Executor.Exec("waitAndStdout", "git", "commit", "--allow-empty", "-m", "Empty commit")
    70  	if err != nil {
    71  		utils.HandleError(err, g.Debug, nil)
    72  		return
    73  	}
    74  }
    75  
    76  func (g *Git) CurrentBranch() string {
    77  	output, err := g.Executor.Exec("actionAndOutput", "git", "branch")
    78  	if err != nil {
    79  		utils.HandleError(err, g.Debug, nil)
    80  		return ""
    81  	}
    82  
    83  	re := regexp.MustCompile(`\*\s(\S*)`)
    84  	match := re.FindStringSubmatch(string(output))
    85  
    86  	if len(match) == 2 {
    87  		return match[1]
    88  	}
    89  
    90  	return ""
    91  }
    92  
    93  func (g *Git) DefaultBranch() string {
    94  	output, err := g.Executor.Exec("actionAndOutput", "git", "symbolic-ref", "refs/remotes/origin/HEAD")
    95  	if err != nil {
    96  		if strings.Contains(err.Error(), "fatal: ") {
    97  			fmt.Printf("\nYour symbolic ref is not set up properly. Please run:\n  git-helper set-head-ref [defaultBranch]\n\nAnd then try your command again.\n\n")
    98  		}
    99  		utils.HandleError(err, g.Debug, nil)
   100  		return ""
   101  	}
   102  
   103  	branch := strings.SplitN(strings.TrimSpace(string(output)), "/", 4)
   104  	if len(branch) != 4 {
   105  		err = errors.New("invalid branch format")
   106  		utils.HandleError(err, g.Debug, nil)
   107  		return ""
   108  	}
   109  
   110  	return branch[3]
   111  }
   112  
   113  func (g *Git) Fetch() {
   114  	_, err := g.Executor.Exec("waitAndStdout", "git", "fetch", "-p")
   115  	if err != nil {
   116  		utils.HandleError(err, g.Debug, nil)
   117  		return
   118  	}
   119  }
   120  
   121  func (g *Git) GetGitRootDir() string {
   122  	output, err := g.Executor.Exec("actionAndOutput", "git", "rev-parse", "--show-toplevel")
   123  	if err != nil {
   124  		utils.HandleError(err, g.Debug, nil)
   125  		return ""
   126  	}
   127  	return strings.TrimSpace(string(output))
   128  }
   129  
   130  func (g *Git) Pull() {
   131  	_, err := g.Executor.Exec("waitAndStdout", "git", "pull")
   132  	if err != nil {
   133  		utils.HandleError(err, g.Debug, nil)
   134  		return
   135  	}
   136  }
   137  
   138  func (g *Git) PushBranch(branch string) {
   139  	_, err := g.Executor.Exec("waitAndStdout", "git", "push", "--set-upstream", "origin", branch)
   140  	if err != nil {
   141  		utils.HandleError(err, g.Debug, nil)
   142  		return
   143  	}
   144  }
   145  
   146  func (g *Git) RepoName() string {
   147  	output, err := g.Executor.Exec("actionAndOutput", "git", "remote", "-v")
   148  	if err != nil {
   149  		utils.HandleError(err, g.Debug, nil)
   150  		return ""
   151  	}
   152  
   153  	remoteURL := string(output)
   154  	re := regexp.MustCompile(`\S\s*\S+.com\S{1}(\S*) \(push\)`)
   155  	match := re.FindStringSubmatch(remoteURL)
   156  	if len(match) >= 2 {
   157  		return strings.Split(match[1], ".git")[0]
   158  	} else {
   159  		err = errors.New("no match found")
   160  		utils.HandleError(err, g.Debug, nil)
   161  	}
   162  
   163  	return ""
   164  }
   165  
   166  func (g *Git) Remotes() []string {
   167  	output, err := g.Executor.Exec("actionAndOutput", "git", "remote", "-v")
   168  	if err != nil {
   169  		utils.HandleError(err, g.Debug, nil)
   170  		return []string{}
   171  	}
   172  
   173  	return strings.Split(string(output), "\n")
   174  }
   175  
   176  func (g *Git) Reset() {
   177  	_, err := g.Executor.Exec("waitAndStdout", "git", "reset", "--hard", "origin/HEAD")
   178  	if err != nil {
   179  		utils.HandleError(err, g.Debug, nil)
   180  		return
   181  	}
   182  }
   183  
   184  func (g *Git) SetHeadRef(defaultBranch string) {
   185  	_, err := g.Executor.Exec("waitAndStdout", "git", "branch", "--set-upstream-to=origin/"+defaultBranch, defaultBranch)
   186  	if err != nil {
   187  		utils.HandleError(err, g.Debug, nil)
   188  		return
   189  	}
   190  
   191  	_, err = g.Executor.Exec("waitAndStdout", "git", "symbolic-ref", "refs/remotes/origin/HEAD", "refs/remotes/origin/"+defaultBranch)
   192  	if err != nil {
   193  		utils.HandleError(err, g.Debug, nil)
   194  		return
   195  	}
   196  }
   197  
   198  func (g *Git) Stash() {
   199  	_, err := g.Executor.Exec("waitAndStdout", "git", "stash")
   200  	if err != nil {
   201  		utils.HandleError(err, g.Debug, nil)
   202  		return
   203  	}
   204  }
   205  
   206  func (g *Git) StashDrop() {
   207  	_, _ = g.Executor.Exec("waitAndStdout", "git", "stash", "drop")
   208  }