mirror of
https://github.com/cooperspencer/gickup.git
synced 2026-10-20 00:17:41 +00:00
* fix: use fresh GitHub App auth for LFS mirror updates * fix: satisfy lint checks
173 lines
3.9 KiB
Go
173 lines
3.9 KiB
Go
package gitcmd
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
type Auth struct {
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
func (a *Auth) Env() []string {
|
|
if a == nil || (a.Username == "" && a.Password == "") {
|
|
return nil
|
|
}
|
|
encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", a.Username, a.Password)))
|
|
return []string{
|
|
"GIT_CONFIG_COUNT=1",
|
|
"GIT_CONFIG_KEY_0=http.extraHeader",
|
|
fmt.Sprintf("GIT_CONFIG_VALUE_0=Authorization: Basic %s", encoded),
|
|
}
|
|
}
|
|
|
|
type GitCmd struct {
|
|
CMD string
|
|
}
|
|
|
|
func New() (GitCmd, error) {
|
|
cmd := exec.CommandContext(context.Background(), "git", "lfs")
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
return GitCmd{}, errors.New("git lfs is not installed")
|
|
}
|
|
|
|
return GitCmd{CMD: "git"}, nil
|
|
}
|
|
|
|
func (g GitCmd) Command(ctx context.Context, auth *Auth, args ...string) *exec.Cmd {
|
|
cmd := exec.CommandContext(ctx, g.CMD, args...)
|
|
if authEnv := auth.Env(); len(authEnv) > 0 {
|
|
cmd.Env = append(os.Environ(), authEnv...)
|
|
}
|
|
return cmd
|
|
}
|
|
|
|
func (g GitCmd) Clone(url, reponame string, bare bool, mirror bool, auth *Auth) error {
|
|
args := []string{"clone", url, reponame}
|
|
if bare {
|
|
args = append(args, "--bare")
|
|
}
|
|
if mirror {
|
|
args = append(args, "--mirror")
|
|
}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) Pull(bare bool, mirror bool, repopath string, auth *Auth) error {
|
|
var args []string
|
|
if bare || mirror {
|
|
args = []string{"-C", repopath, "fetch", "--all"}
|
|
} else {
|
|
args = []string{"-C", repopath, "pull", "--all"}
|
|
}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) Fetch(path string, auth *Auth) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "fetch", "--all", "--tags"}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) LFSFetch(path string, auth *Auth) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "lfs", "fetch", "--all"}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) MirrorPull(path string, auth *Auth) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "pull", "--all", "--tags"}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) NewRemote(name, url, path string) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "remote", "add", name, url}
|
|
cmd := g.Command(context.Background(), nil, args...)
|
|
|
|
return cmd.Run()
|
|
}
|
|
|
|
func (g GitCmd) Push(path, remote string, auth *Auth) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "push", "--all", remote}
|
|
cmd := g.Command(context.Background(), auth, args...)
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
var exitErr *exec.ExitError
|
|
if errors.As(err, &exitErr) {
|
|
return fmt.Errorf("%s", strings.TrimSuffix(string(output), "\n"))
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func (g GitCmd) Checkout(path, branch string) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"checkout", branch}
|
|
cmd := g.Command(context.Background(), nil, args...)
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
var exitErr *exec.ExitError
|
|
if errors.As(err, &exitErr) {
|
|
return fmt.Errorf("%s", strings.TrimSuffix(string(output), "\n"))
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func (g GitCmd) SSHPush(path, remote, key string) error {
|
|
_, err := os.Stat(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
args := []string{"-C", path, "push", "--all", remote}
|
|
cmd := g.Command(context.Background(), nil, args...)
|
|
cmd.Env = append(os.Environ(), fmt.Sprintf("GIT_SSH_COMMAND=ssh -i %s", key))
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
var exitErr *exec.ExitError
|
|
if errors.As(err, &exitErr) {
|
|
return fmt.Errorf("%s", strings.TrimSuffix(string(output), "\n"))
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|