git-ea/cmd/cmd.go

87 lines
1.8 KiB
Go

package cmd
import (
"context"
"os"
"os/exec"
"regexp"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/rs/zerolog/log"
)
func run(ctx context.Context, cmd string, args ...string) error {
c := exec.CommandContext(ctx, cmd, args...)
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Stdin = os.Stdin
return c.Run()
}
func fetch(ctx context.Context) {
if err := run(ctx, "git", "fetch", "upstream"); err != nil {
log.Err(err).Msg("")
}
}
func isClean() bool {
c := exec.Command("git", "status", "--porcelain")
o, err := c.Output()
if err != nil {
log.Fatal().Err(err).Msg("could not get git status")
}
return len(o) == 0
}
func repo() *git.Repository {
repo, err := git.PlainOpenWithOptions(".", &git.PlainOpenOptions{
DetectDotGit: true,
})
if err != nil {
log.Fatal().Err(err).Msg("cannot open git repository")
}
return repo
}
func worktree() *git.Worktree {
tree, err := repo().Worktree()
if err != nil {
log.Fatal().Err(err).Msg("cannot get git worktree")
}
return tree
}
func head(name string) plumbing.Hash {
ref, err := repo().Reference(plumbing.NewRemoteReferenceName("upstream", name), false)
if err != nil {
log.Fatal().Err(err).Msgf("cannot get remote upstream %s HEAD", name)
}
return ref.Hash()
}
var releaseRe = regexp.MustCompile(`release/v1\.(\d+)`)
func latestRelease() string {
cmd := exec.Command("git", "ls-remote", "upstream", "release/*")
out, err := cmd.Output()
if err != nil {
log.Fatal().Err(err).Msg("could not get latest release")
}
matches := releaseRe.FindAllStringSubmatch(string(out), -1)
var latest string
for _, match := range matches {
m := match[1]
if len(m) < 3 {
m = strings.Repeat("0", 3-len(m)) + m
}
if m > latest {
latest = m
}
}
return strings.TrimLeft(latest, "0")
}