summaryrefslogtreecommitdiff
path: root/gitTag.update.go
blob: c8a35c33486ecaf499a885255c32cf9d93fe151e (plain)
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
}