diff options
Diffstat (limited to 'stat.makeRemoteRefs.go')
| -rw-r--r-- | stat.makeRemoteRefs.go | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/stat.makeRemoteRefs.go b/stat.makeRemoteRefs.go new file mode 100644 index 0000000..e47938a --- /dev/null +++ b/stat.makeRemoteRefs.go @@ -0,0 +1,144 @@ +package gitpb + +import ( + "errors" + "fmt" + "path/filepath" + "slices" + "strings" + + "go.wit.com/lib/config" + "go.wit.com/lib/env" + "go.wit.com/log" +) + +// returns err if anything changes or anything is wrong (todo: should these be different?) +func (r *Repo) LoadRemoteRefs(remoteName string) (*Stats, error) { + fullname := filepath.Join(r.FullPath, ".git", remoteName+".refs.pb") + stats := NewStats() + stats.Filename = fullname + err := config.ForceCreatePB(stats) + return stats, err +} + +// cmd := []string{"git", "show-ref"} // must use 'master' as queried from the git server +// cmd := []string{"git", "log", "-n", "100", makeFmts(), "origin/HEAD"} // HEAD is _NOT_ always set +// cmd := []string{"git", "show-ref"} // must use 'master' as queried from the git server +// cmd := []string{"git", "log", "-n", "100", makeFmts(), "origin/HEAD"} // HEAD is _NOT_ always set + +// returns err if anything changes or anything is wrong (todo: should these be different?) +func (r *Repo) MakeRemoteRefs(remoteName string) (*Stats, error) { + stats, err := r.LoadRemoteRefs(remoteName) + if err != nil { + return stats, err + } + if stats.Len() != 0 { + return stats, errors.New("refs file was already created") + } + cmd := []string{"git", "ls-remote", remoteName} // must use 'master' as queried from the git server // GO has 250k remote refs + if env.True("stats") { + log.Info("STATS VERBOSE Run:", cmd) + } + cmdout := r.Run(cmd) + if len(cmdout.Stdout) == 0 { + return stats, errors.New("got nothing from git ls-remote") + } + var counter int + for _, line := range cmdout.Stdout { + line = strings.TrimSpace(line) + parts := strings.Fields(line) + if len(parts) != 2 { + log.Printf("Repo: %s\n", r.FullPath) + log.Printf("CMD: %v\n", cmd) + log.Printf("LINE:%s\n", line) + return stats, errors.New(line) + } + if env.True("stats") { + log.Printf("LINE:%v %d %s\n", parts, counter, r.FullPath) + } + counter += 1 + newstat := new(Stat) + newstat.Hash = parts[0] + stats.Append(newstat) + } + if counter > 0 { + stats.SaveByHash() + } + return stats, nil +} + +func (x *Stats) SaveByHash() error { + newx := NewStats() + + all := x.SortByHash() + for all.Scan() { + r := all.Next() + newx.Clone(r) + } + + newx.Filename = x.Filename + err := newx.Save() + + return err +} + +// returns err if anything changes or anything is wrong (todo: should these be different?) +func (r *Repo) UpdateRemoteRefs(remoteName string) error { + stats, err := r.LoadRemoteRefs(remoteName) + if err != nil { + return err + } + if stats.Len() == 0 { + return errors.New("need to make file instead") + } + cmd := []string{"git", "ls-remote", remoteName} // must use 'master' as queried from the git server // GO has 250k remote refs + if env.True("stats") { + log.Info("STATS VERBOSE Run:", cmd) + } + cmdout := r.Run(cmd) + if len(cmdout.Stdout) == 0 { + return errors.New("got nothing back") + } + var ticker int + var counter int + var allnew []*Stat + for _, line := range cmdout.Stdout { + line = strings.TrimSpace(line) + parts := strings.Fields(line) + if len(parts) != 2 { + log.Printf("Repo: %s\n", r.FullPath) + log.Printf("CMD: %v\n", cmd) + log.Printf("LINE:%s\n", line) + return errors.New(line) + } + if env.True("stats") { + log.Printf("LINE:%v %d %s\n", parts, ticker, r.FullPath) + } + // refpath := filepath.Join("refs/remote", remoteName) + // if strings.HasPrefix(parts[1], refpath) { + // this ref is not from the remote + // continue + // } + counter += 1 + newstat := new(Stat) + newstat.Hash = parts[0] + n, found := slices.BinarySearchFunc(stats.Stats, newstat, func(a, b *Stat) int { + return strings.Compare(a.Hash, b.Hash) + }) + _ = n + + if found { + // log.Info("found", n) + continue + } + ticker += 1 + log.Info("not found", newstat) + allnew = append(allnew, newstat) + } + if ticker > 0 { + stats.Stats = append(stats.Stats, allnew...) + stats.SaveByHash() + return errors.New(fmt.Sprintf("len(%d), ticker(%d) counter(%d) refs changed", stats.Len(), ticker, counter)) + } + return nil +} |
