package githelper import ( "errors" "os" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport/ssh" "github.com/sirupsen/logrus" ) type Git struct { SshPrivateKeyPath string } func NewGit(sshPrivateKeyPath string) Githelper { return &Git{ SshPrivateKeyPath: sshPrivateKeyPath, } } func (g *Git) CloneRepo(workdir, gitURL string, dry bool) error { // TODO(@allanger): Support ssh keys with passwords publicKeys, err := ssh.NewPublicKeysFromFile("git", g.SshPrivateKeyPath, "") if err != nil { return err } _, err = git.PlainClone(workdir, false, &git.CloneOptions{URL: gitURL, Auth: publicKeys}) if err != nil && !errors.Is(err, git.ErrEmptyUrls) { logrus.Info("the repo seems to be empty, I'll try to bootsrap it") // Initialize the repo err := os.Mkdir(workdir, 0077700) if err != nil { return err } r, err := git.PlainInit(workdir, false) if err != nil { return err } logrus.Infof("adding an origin remote: %s", gitURL) if _, err := r.CreateRemote(&config.RemoteConfig{Name: "origin", URLs: []string{gitURL}}); err != nil { return err } logrus.Info("getting the worktree") w, err := r.Worktree() if err != nil { return err } if err := r.Storer.SetReference(plumbing.NewHashReference(plumbing.Main, plumbing.ZeroHash)); err != nil { return err } logrus.Info("creating an empty 'Init Commit'") if _, err := w.Commit("Init Commit", &git.CommitOptions{ AllowEmptyCommits: true, }); err != nil { return err } if !dry { if err := r.Push(&git.PushOptions{RemoteName: "origin"}); err != nil { return err } } } else if err != nil { return err } return nil } func (g *Git) AddAllAndCommit(workdir, message string) (string, error) { r, err := git.PlainOpen(workdir) if err != nil { return "", err } w, err := r.Worktree() if err != nil { return "", err } if _, err := w.Add("."); err != nil { return "", err } sha, err := w.Commit(message, &git.CommitOptions{}) if err != nil { return "", err } return sha.String(), nil } func (g *Git) Push(workdir string) error { r, err := git.PlainOpen(workdir) if err != nil { return err } publicKeys, err := ssh.NewPublicKeysFromFile("git", g.SshPrivateKeyPath, "") if err != nil { return err } if err := r.Push(&git.PushOptions{ RemoteName: "origin", Auth: publicKeys, }); err != nil { return err } return nil }