summaryrefslogtreecommitdiff
path: root/doReload.go
diff options
context:
space:
mode:
Diffstat (limited to 'doReload.go')
-rw-r--r--doReload.go263
1 files changed, 263 insertions, 0 deletions
diff --git a/doReload.go b/doReload.go
new file mode 100644
index 0000000..ac57d3c
--- /dev/null
+++ b/doReload.go
@@ -0,0 +1,263 @@
+// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
+// Use of this source code is governed by the GPL 3.0
+
+package main
+
+import (
+ "errors"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ "go.wit.com/lib/env"
+ "go.wit.com/lib/protobuf/gitpb"
+ "go.wit.com/log"
+)
+
+func searchRemote(remote *gitpb.Stats, ref *gitpb.Stat) *gitpb.Stat {
+ n, found := slices.BinarySearchFunc(remote.Stats, ref, func(a, b *gitpb.Stat) int {
+ return strings.Compare(a.Hash, b.Hash)
+ })
+
+ if found {
+ foundref := remote.Stats[n]
+ if ref.Hash != foundref.Hash {
+ log.Info("Something went wrong", ref.Hash, foundref.Hash)
+ return nil
+ }
+ return foundref
+ }
+ log.Printf("searchRemote(nil) len(%d) NOT FOUND: %v\n", remote.Len(), ref)
+ for remoteref := range remote.IterAll() {
+ if remoteref.Hash == ref.Hash {
+ log.Printf("searchRemote(nil) len(%d) FOUND: %v\n", remote.Len(), remoteref)
+ return remoteref
+ }
+ if remoteref.TreeHash == ref.Hash {
+ log.Printf("searchRemote(nil) len(%d) FOUND: %v\n", remote.Len(), remoteref)
+ return remoteref
+ }
+ if remoteref.TagHash == ref.Hash {
+ log.Printf("searchRemote(nil) len(%d) FOUND: %v\n", remote.Len(), remoteref)
+ return remoteref
+ }
+ // log.Printf("searchRemote(nil) len(%d) NO MATCH: %s %s %s\n", remote.Len(), remoteref.Hash, remoteref.TreeHash, "nope")
+ }
+ log.Printf("searchRemote(nil) len(%d) NOT FOUND: %v\n", remote.Len(), ref)
+ return nil
+}
+
+// processes stats.Tags in the remote refs .pb
+// tries to find the tags in the local refs.pb file
+func doMapTags(r *gitpb.Repo) (*gitpb.Stats, error) {
+ var allerr error
+ stats, err := r.LoadRefs()
+ if err != nil {
+ return stats, err
+ }
+
+ var worked bool
+ // look through the Tags
+ for _, rmote := range r.Config.Remotes {
+ remotestats, err := r.LoadRemote(rmote.Name)
+ if err != nil {
+ return stats, err
+ }
+ if remotestats.Len() == 0 {
+ // need to init remote stats
+ return stats, errors.New("run dev stats --update-remote")
+ }
+ for ref := range remotestats.IterAll() {
+ if ref.Tags == "" {
+ continue
+ }
+ line := strings.TrimSpace(ref.Tags)
+ line = strings.TrimPrefix(line, "(")
+ line = strings.TrimSuffix(line, ")")
+ for _, part := range strings.Split(line, ",") {
+ var found bool
+ var tag string
+ part = strings.TrimSpace(part)
+ parts := strings.Split(part, " ")
+ if (len(parts) == 2) && (parts[0] == "tag:") {
+ tag = filepath.Join("refs/tags", parts[1])
+ } else if len(parts) == 1 {
+ tag = parts[0]
+ if strings.HasPrefix(tag, rmote.Name+"/") {
+ tag = filepath.Join("refs/remotes", tag)
+ } else {
+ tag = filepath.Join("refs/heads", tag)
+ }
+ } else if len(parts) == 3 {
+ if parts[0] == "HEAD" {
+ tag = filepath.Join("refs/heads", parts[2])
+ }
+ } else {
+ log.Printf("hash(%s) could not find tag: (%v)\n", ref.Hash, parts)
+ }
+ for tagref := range stats.IterAll() {
+ if tagref.Name == tag {
+ found = true
+ if tagref.Hash == "" {
+ log.Printf("Found taghash(%s) hash(%s) has tags: %s (%s)\n", tagref.TagHash, ref.Hash, part, tag)
+ tagref.Hash = ref.Hash
+ worked = true
+ } else {
+ if tagref.Hash != ref.Hash {
+ log.Printf("EVEN WEIRDER ERROR: taghash(%s) hash(%s) has tags: %s (%s)\n", tagref.TagHash, ref.Hash, part, tag)
+ }
+ }
+ }
+ }
+ if !found {
+ s := log.Sprintf("ref.hash(%s) could not find tag(%s) in remote. part=(%s)", ref.Hash, tag, part)
+ log.Info(s)
+ allerr = errors.New(s)
+ }
+ }
+ }
+ }
+ if worked {
+ stats.Save()
+ return stats, errors.New("New tags found!")
+ }
+ return stats, allerr
+}
+
+func remoteDups(all *gitpb.Stats) error {
+ var dups []*gitpb.Stat
+ last := new(gitpb.Stat)
+ for ref := range all.IterAll() {
+ if ref.Hash == last.Hash {
+ dups = append(dups, ref)
+ } else {
+ last = ref
+ }
+ }
+ s := log.Sprintf("found %d dups", len(dups))
+ log.Info(s, dups)
+ if len(dups) == 0 {
+ return nil
+ }
+ return errors.New(s)
+}
+
+func makeAllGitStats(r *gitpb.Repo) error {
+ var err error
+
+ // make all the remote files before the local files
+ for _, rmote := range r.Config.Remotes {
+ morestats, err := r.MakeRemote(rmote.Name)
+ if err != nil {
+ return errors.Join(err, errors.New("MakeRemote() failed"))
+ }
+ if env.True("resort") {
+ morestats.SaveByHash()
+ return errors.New("stats should have been resorted and saved")
+ }
+
+ remoterefs, err := r.MakeRemoteRefs(rmote.Name)
+ if err != nil {
+ return errors.Join(err, errors.New("MakeRemoteRefs() failed"))
+ }
+ if env.True("resort") {
+ remoterefs.SaveByHash()
+ return errors.New("stats should have been resorted and saved")
+ }
+ }
+
+ // make the local refs pb
+ stats, err := r.LoadRefs()
+ if err != nil {
+ return errors.Join(err, errors.New("r.LoadRefs() failed"))
+ }
+
+ if env.True("resort") {
+ stats.SaveByHash()
+ log.Info("stats should have been resorted and saved")
+ return nil
+ }
+
+ err = r.UpdateRefs(stats)
+ if err != nil {
+ return errors.Join(err, errors.New("r.UpdateRefs() failed"))
+ }
+ return nil
+}
+
+func doReload(r *gitpb.Repo) error {
+ err := makeAllGitStats(r)
+ if err != nil {
+ return err
+ }
+
+ stats, err := doMapTags(r)
+ if err != nil {
+ return errors.Join(err, errors.New("doMapTags() failed"))
+ }
+
+ // * remotes duplicates
+ // * sets fields that might have not been set before
+ // this probably should go away once the other code works
+ for _, rmote := range r.Config.Remotes {
+ remotestats, err := r.LoadRemote(rmote.Name)
+ if err != nil {
+ return err
+ }
+ var save bool
+ remoteDups(remotestats)
+ for ref := range stats.IterAll() {
+ found := searchRemote(remotestats, ref)
+ if found == nil {
+ log.Printf("len(%d) NOT FOUND: %v\n", remotestats.Len(), ref)
+ return nil
+ }
+ if ref.SanitizedSubject != found.SanitizedSubject {
+ log.Info("subject", ref.SanitizedSubject, found.SanitizedSubject)
+ ref.SanitizedSubject = found.SanitizedSubject
+ save = true
+ }
+ if (ref.AuthorTime == nil) || (ref.AuthorTime.AsTime() != found.AuthorTime.AsTime()) {
+ log.Info("author time", ref.AuthorTime, found.AuthorTime)
+ ref.AuthorTime = found.AuthorTime
+ save = true
+ }
+ if (ref.CommitTime == nil) || (ref.CommitTime.AsTime() != found.CommitTime.AsTime()) {
+ log.Info("commit time", ref.CommitTime, found.CommitTime)
+ ref.CommitTime = found.CommitTime
+ save = true
+ }
+ }
+ if save {
+ stats.Save()
+ return errors.New("some things were updated")
+ }
+ }
+
+ /*
+ sort.Slice(stats, func(i, j int) bool {
+ return gitpb.
+ })
+ */
+
+ // sorts refs by version. tries, but the sort doesn't quite work yet for some reason
+ // saves the sorted file
+ wasSorted := stats.SortVersion()
+ if !wasSorted {
+ newstats := gitpb.NewStats()
+ for _, ref := range stats.Stats {
+ newstats.Clone(ref)
+ }
+ newstats.Filename = stats.Filename
+ newstats.Save()
+ }
+ footer := stats.PrintTableLimit(2)
+ log.Info("doReload() footer:", footer)
+
+ /*
+ footer := stats.PrintTable()
+ log.Info("doReload() footer:", footer)
+ */
+
+ return nil
+}