1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
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"
)
// Update repo.Refs from .git/
func (repo *Repo) UpdateGitTags() 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
}
|