From c75dfcd8496a6e61711e278194e59686e1e284a0 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Wed, 5 Nov 2025 11:17:19 -0600 Subject: almost working stats.proto --- doReload.go | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 doReload.go (limited to 'doReload.go') 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 +} -- cgit v1.2.3