summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-11-29 01:23:51 -0600
committerJeff Carr <[email protected]>2024-11-29 01:23:51 -0600
commit96d37b5941717f9c3852429ba25420c6ccb3f997 (patch)
tree96ce9881925f71ea41effd3660ef24c318ddad61
parent3b90d979d73da9896570d2dc927e05e769b9670b (diff)
rename this protobuf to something more specific
-rw-r--r--Makefile8
-rw-r--r--gitTags.proto13
-rw-r--r--gitTags.query.go78
-rw-r--r--gitTags.sort.go149
-rw-r--r--gitTags.update.go83
-rw-r--r--refs.update.go13
-rw-r--r--repos.new.go1
-rw-r--r--repos.proto3
8 files changed, 334 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 7fb1b82..ffbb48f 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
# go install
-all: refs.pb.go godep.pb.go repos.pb.go vet
+all: refs.pb.go gitTags.pb.go godep.pb.go repos.pb.go vet
make -C scanGoSrc/
vet: lint
@@ -34,6 +34,11 @@ refs.pb.go: refs.proto
--go_opt=Mrefs.proto=go.wit.com/lib/protobuf/gitpb \
refs.proto
+gitTags.pb.go: gitTags.proto
+ cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \
+ --go_opt=MgitTags.proto=go.wit.com/lib/protobuf/gitpb \
+ gitTags.proto
+
godep.pb.go: godep.proto
cd ~/go/src && protoc --go_out=. --proto_path=go.wit.com/lib/protobuf/gitpb \
--go_opt=Mgodep.proto=go.wit.com/lib/protobuf/gitpb \
@@ -44,4 +49,5 @@ repos.pb.go: repos.proto
--go_opt=Mrefs.proto=go.wit.com/lib/protobuf/gitpb \
--go_opt=Mgodep.proto=go.wit.com/lib/protobuf/gitpb \
--go_opt=Mrepos.proto=go.wit.com/lib/protobuf/gitpb \
+ --go_opt=MgitTags.proto=go.wit.com/lib/protobuf/gitpb \
repos.proto
diff --git a/gitTags.proto b/gitTags.proto
new file mode 100644
index 0000000..dd3d77a
--- /dev/null
+++ b/gitTags.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package gitpb;
+
+import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
+
+message GitTag {
+ string refname = 1; // tag name. treated as unique
+ google.protobuf.Timestamp creatordate = 2; // git creatordate
+ google.protobuf.Timestamp authordate = 3; // git creatordate
+ string objectname = 4; // git hash
+ string subject = 5; // git tag subject
+}
diff --git a/gitTags.query.go b/gitTags.query.go
new file mode 100644
index 0000000..faea8e2
--- /dev/null
+++ b/gitTags.query.go
@@ -0,0 +1,78 @@
+package gitpb
+
+// runs git, parses output
+// types faster than you can
+
+import (
+ "go.wit.com/log"
+)
+
+func (repo *Repo) GetLastTag() string {
+ cmd := []string{"git", "rev-list", "--tags", "--max-count=1"}
+ result := repo.RunQuiet(cmd)
+ log.Info("getLastTagVersion()", result.Stdout)
+
+ if len(result.Stdout) != 1 {
+ log.Info("git LastTag() error:", result.Stdout)
+ return "error"
+ }
+
+ hash := result.Stdout[0]
+
+ cmd = []string{"git", "describe", "--tags", "--always", hash}
+ result = repo.RunQuiet(cmd)
+
+ if len(result.Stdout) != 1 {
+ log.Info("git LastTag() error:", result.Stdout)
+ return "error"
+ }
+
+ return result.Stdout[0]
+}
+
+/*
+func (repo *Repo) gitDescribeByName(name string) (string, error) {
+ name = strings.TrimSpace(name)
+
+ if name == "" {
+ // git will return the current tag
+ r := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"})
+ output := strings.Join(r.Stdout, "\n")
+ if r.Error != nil {
+ log.Warn("gitDescribeByName() not in a git repo?", r.Error, repo.GoPath)
+ }
+ return strings.TrimSpace(output), r.Error
+ }
+ if !repo.LocalTagExists(name) {
+ // tag does not exist
+ return "", errors.New("gitDescribeByName() git fatal: Not a valid object name")
+ }
+ cmd := []string{"git", "describe", "--tags", "--always", name}
+ r := repo.RunQuiet(cmd)
+ output := strings.Join(r.Stdout, "\n")
+ if r.Error != nil {
+ log.Warn("cmd =", cmd)
+ log.Warn("err =", r.Error)
+ log.Warn("not in a git repo or bad tag?", rs.Path())
+ }
+
+ return strings.TrimSpace(output), r.Error
+}
+
+func (repo *Repo) LocalTagExists(findname string) bool {
+ allTags := repo.Tags.ListAll()
+ for _, t := range allTags {
+ tagname := t.TagString()
+ if strings.HasPrefix(tagname, "refs/remotes") {
+ continue
+ }
+ path, filename := filepath.Split(tagname)
+ log.Log(INFO, "tag:", path, filename, "from", rs.Path())
+ if filename == findname {
+ log.Log(INFO, "found tag:", path, filename, "from", rs.Path())
+ return true
+ }
+ }
+ return false
+}
+*/
diff --git a/gitTags.sort.go b/gitTags.sort.go
new file mode 100644
index 0000000..8d4305f
--- /dev/null
+++ b/gitTags.sort.go
@@ -0,0 +1,149 @@
+package gitpb
+
+// this is becoming a standard format
+// todo: autogenerate this from the .proto file?
+
+import (
+ "fmt"
+ "os"
+ "sort"
+ sync "sync"
+ "time"
+)
+
+// bad global lock until I figure out some other plan
+var gitTagslock sync.RWMutex
+
+type GitTagIterator struct {
+ sync.RWMutex
+
+ packs []*GitTag
+ index int
+}
+
+// NewGitTagIterator initializes a new iterator.
+func NewGitTagIterator(packs []*GitTag) *GitTagIterator {
+ return &GitTagIterator{packs: packs}
+}
+
+// Scan moves to the next element and returns false if there are no more packs.
+func (it *GitTagIterator) Scan() bool {
+ if it.index >= len(it.packs) {
+ return false
+ }
+ it.index++
+ return true
+}
+
+// GitTag returns the current repo.
+func (it *GitTagIterator) GitTag() *GitTag {
+ if it.packs[it.index-1] == nil {
+ for i, d := range it.packs {
+ fmt.Println("i =", i, d)
+ }
+ fmt.Println("len =", len(it.packs))
+ fmt.Println("repo == nil", it.index, it.index-1)
+ os.Exit(-1)
+ }
+ return it.packs[it.index-1]
+}
+
+// Use Scan() in a loop, similar to a while loop
+//
+// for iterator.Scan() {
+// d := iterator.GitTag()
+// fmt.Println("GitTag UUID:", d.Uuid)
+// }
+
+func (r *Repo) AllTags() *GitTagIterator {
+ repoPointers := r.selectAllGitTags()
+
+ iterator := NewGitTagIterator(repoPointers)
+ return iterator
+}
+
+func (r *Repo) SortTagsByName() *GitTagIterator {
+ packs := r.selectAllGitTags()
+
+ sort.Sort(GitTagsByName(packs))
+
+ iterator := NewGitTagIterator(packs)
+ return iterator
+}
+
+// enforces no duplicate package names
+func (repo *Repo) AppendGitTag(newP *GitTag) bool {
+ gitTagslock.Lock()
+ defer gitTagslock.Unlock()
+
+ for _, p := range repo.GitTags {
+ if p.Refname == newP.Refname {
+ return false
+ }
+ }
+
+ repo.GitTags = append(repo.GitTags, newP)
+ return true
+}
+
+// returns time.Duration since last Update()
+func (r *GitTag) Age(newP *GitTag) time.Duration {
+ t := time.Since(r.Creatordate.AsTime())
+ return t
+}
+
+// find a package by name
+func (repo *Repo) FindGitTagByName(name string) *GitTag {
+ gitTagslock.RLock()
+ defer gitTagslock.RUnlock()
+
+ for _, p := range repo.GitTags {
+ if p.Refname == name {
+ return p
+ }
+ }
+
+ return nil
+}
+
+func (repo *Repo) LenGitTags() int {
+ gitTagslock.RLock()
+ defer gitTagslock.RUnlock()
+
+ return len(repo.GitTags)
+}
+
+type GitTagsByName []*GitTag
+
+func (a GitTagsByName) Len() int { return len(a) }
+func (a GitTagsByName) Less(i, j int) bool { return a[i].Refname < a[j].Refname }
+func (a GitTagsByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// safely returns a slice of pointers to the GitTag protobufs
+func (repo *Repo) selectAllGitTags() []*GitTag {
+ gitTagslock.RLock()
+ defer gitTagslock.RUnlock()
+
+ // Create a new slice to hold pointers to eachGitTag
+ var allGitTags []*GitTag
+ allGitTags = make([]*GitTag, len(repo.GitTags))
+ for i, p := range repo.GitTags {
+ allGitTags[i] = p // Copy pointers for safe iteration
+ }
+
+ return allGitTags
+}
+
+func (repo *Repo) DeleteTagByHash(hash string) *GitTag {
+ gitTagslock.Lock()
+ defer gitTagslock.Unlock()
+
+ for i, _ := range repo.GitTags {
+ if repo.GitTags[i].Objectname == hash {
+ repo.GitTags[i] = repo.GitTags[len(repo.GitTags)-1]
+ repo.GitTags = repo.GitTags[:len(repo.GitTags)-1]
+ return nil
+ }
+ }
+ return nil
+}
diff --git a/gitTags.update.go b/gitTags.update.go
new file mode 100644
index 0000000..465fe70
--- /dev/null
+++ b/gitTags.update.go
@@ -0,0 +1,83 @@
+package gitpb
+
+import (
+ "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 {
+ // delete the old hash
+ // r.DeleteByHash(hash)
+ repo.GitTags = nil
+
+ 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,
+ Objectname: hash,
+ Subject: subject,
+ Creatordate: ctime,
+ Authordate: atime,
+ }
+
+ repo.AppendGitTag(&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
+}
diff --git a/refs.update.go b/refs.update.go
index 3266fd1..e4d0413 100644
--- a/refs.update.go
+++ b/refs.update.go
@@ -61,16 +61,3 @@ func (repo *Repo) UpdateGit() error {
repo.AppendRef(&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
-}
diff --git a/repos.new.go b/repos.new.go
index bab2b25..8638da7 100644
--- a/repos.new.go
+++ b/repos.new.go
@@ -34,6 +34,7 @@ func (all *Repos) NewGoPath(basepath string, gopath string) (*Repo, error) {
GoPath: gopath,
}
newr.UpdateGit()
+ newr.UpdateGitTags()
all.add(&newr)
return &newr, nil
diff --git a/repos.proto b/repos.proto
index 029bad2..9e02c08 100644
--- a/repos.proto
+++ b/repos.proto
@@ -7,6 +7,7 @@ package gitpb;
import "refs.proto";
import "godep.proto";
+import "gitTags.proto";
import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp
message Repo {
@@ -20,6 +21,8 @@ message Repo {
google.protobuf.Timestamp lastGoDep = 7; // last time go.sum was processed
bool goLibrary = 8; // if this is a golang library
bool goPrimitive = 9; // if this is a golang primitive
+
+ repeated GitTag gitTags = 10;
}
message Repos {