114 lines
2.4 KiB
Go
114 lines
2.4 KiB
Go
|
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) 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
|
||
|
}
|
||
|
|
||
|
if _, err := w.Commit(message, &git.CommitOptions{}); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return 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
|
||
|
}
|