140 lines
3.4 KiB
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
|
||
|
}
|