gitpb/reloadTags.go

140 lines
3.4 KiB
Go

package gitpb
import (
"path/filepath"
"slices"
"strings"
"time"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
)
// reload the tags
func (repo *Repo) reloadGitTags() error {
// todo: look for changes in the tags?
repo.Tags = new(GitTags)
tags := []string{"%(objectname)", "%(creatordate)", "%(*authordate)", "%(refname)", "%(subject)"}
format := strings.Join(tags, "_,,,_")
cmd := []string{"git", "for-each-ref", "--sort=taggerdate", "--format", format}
// log.Info("RUNNING:", strings.Join(cmd, " "))
result := shell.PathRunQuiet(repo.FullPath, cmd)
if result.Error != nil {
log.Warn("git for-each-ref error:", result.Error)
return result.Error
}
lines := result.Stdout
// reverse the git order
slices.Reverse(lines)
var refname string
var hash string
var subject string
var ctime *timestamppb.Timestamp
var atime *timestamppb.Timestamp
for i, line := range lines {
var parts []string
parts = make([]string, 0)
parts = strings.Split(line, "_,,,_")
if len(parts) != 5 {
log.Info("tag error:", i, parts)
continue
}
hash = parts[0]
if parts[1] != "" {
tmp := getGitDateStamp(parts[1])
ctime = timestamppb.New(tmp)
}
if parts[2] != "" {
tmp := getGitDateStamp(parts[2])
atime = timestamppb.New(tmp)
}
refname = parts[3]
subject = parts[4]
newr := GitTag{
Refname: refname,
Hash: hash,
Subject: subject,
Creatordate: ctime,
Authordate: atime,
}
repo.Tags.Append(&newr)
}
return nil
}
// converts a git for-each-ref date. "Wed Feb 7 10:13:38 2024 -0600"
func getGitDateStamp(gitdefault string) time.Time {
// now := time.Now().Format("Wed Feb 7 10:13:38 2024 -0600")
const gitLayout = "Mon Jan 2 15:04:05 2006 -0700"
tagTime, err := time.Parse(gitLayout, gitdefault)
if err != nil {
log.Warn("GOT THIS IN PARSE AAA." + gitdefault + ".AAA")
log.Warn(err)
return time.Now()
}
return tagTime
}
func (tag *GitTag) GetAge() time.Duration {
return time.Since(tag.GetAuthordate().AsTime())
}
func (repo *Repo) NewestTag() *GitTag {
loop := repo.Tags.SortByAge()
for loop.Scan() {
r := loop.Next()
return r
}
return nil
}
func (repo *Repo) LocalTagExists(findname string) bool {
loop := repo.Tags.SortByRefname()
for loop.Scan() {
ref := loop.Next()
// log.Info(repo.GoPath, ref.Refname)
if strings.HasPrefix(ref.Refname, "refs/remotes") {
continue
}
_, tagname := filepath.Split(ref.Refname)
// log.Info("tag:", path, tagname, "from", repo.GoPath)
if tagname == findname {
// log.Info("found tag:", path, tagname, "from", repo.GoPath)
return true
}
}
return false
}
// returns true if 'taggy' is _ONLY_ a local tag
// this means you can not do a git pull or git push on it
func (repo *Repo) IsOnlyLocalTag(taggy string) bool {
// first make sure the tag is actually even local
if !repo.LocalTagExists(taggy) {
// this means it's not even local now.
return false
}
// okay, taggy exists, does it exist in a remote repo?
loop := repo.Tags.SortByRefname()
for loop.Scan() {
ref := loop.Next()
tagname := ref.Refname
if strings.HasPrefix(tagname, "refs/remotes") {
path, filename := filepath.Split(tagname)
if filename == taggy {
log.Log(GITPB, "found tag:", path, filename, "from", repo.GetGoPath())
return false
}
}
}
// we couldn't find the local tag anywhere remote, so it's probably only local
return true
}