summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--argv.go1
-rw-r--r--doDev.go39
-rw-r--r--doStats.go197
-rw-r--r--doVerifyNamespace.go35
4 files changed, 259 insertions, 13 deletions
diff --git a/argv.go b/argv.go
index b0d3799..1b76e4d 100644
--- a/argv.go
+++ b/argv.go
@@ -106,6 +106,7 @@ type DevCmd struct {
URL string `arg:"--connect" help:"forge url"`
Stats *StatsCmd `arg:"subcommand:stats" help:"generate origin.pb"`
Namespace *EmptyCmd `arg:"subcommand:namespace" help:"check the namespaces"`
+ GitConfig *EmptyCmd `arg:"subcommand:gitconfig" help:"check the .git/config files"`
}
type GenerateCmd struct {
diff --git a/doDev.go b/doDev.go
index 7568f04..2c0b973 100644
--- a/doDev.go
+++ b/doDev.go
@@ -3,7 +3,10 @@
package main
-import "go.wit.com/lib/env"
+import (
+ "go.wit.com/lib/env"
+ "go.wit.com/log"
+)
// so don't delete them
func doDev() (string, error) {
@@ -25,10 +28,34 @@ func doDev() (string, error) {
s, err = doStats(argv.Dev.Stats)
return s, err
}
+
if argv.Dev.Namespace != nil {
- s, err = doVerifyNamespace()
- return s, err
+ fixed := me.forge.RunOnRepos(me.forge.Repos, doCleanNamespace)
+ if fixed.Len() == 0 {
+ return "no namespaces changed", nil
+ }
+
+ // show the changed repos & save cache .pb file
+ fixed = fixed.SortActual()
+ footer := me.forge.PrintDefaultTB(fixed)
+ me.forge.Repos.SaveVerbose()
+ return "changed namespaces: " + footer, nil
}
+
+ if argv.Dev.GitConfig != nil {
+ // me.forge.ConfigRill(1, 1)
+ fixed := me.forge.RunOnRepos(me.forge.Repos, doGitConfig)
+ if fixed.Len() == 0 {
+ return "no git config changes", nil
+ }
+
+ // show the changed repos & save cache .pb file
+ fixed = fixed.SortActual()
+ footer := me.forge.PrintErrorsTB(fixed)
+ me.forge.Repos.SaveVerbose()
+ return ".git/config problems: " + footer, nil
+ }
+
if argv.Dev.GoWork != nil {
s, err = doGoWork()
return s, err
@@ -48,5 +75,11 @@ func doDev() (string, error) {
return "build ok", nil
}
+ if env.True("stats") {
+ log.Info("STATS VERBOSE")
+ } else {
+ log.Info("STATS not VERBOSE")
+ }
+
return "no dev subcommand", nil
}
diff --git a/doStats.go b/doStats.go
index 8afcaa8..5fc5be4 100644
--- a/doStats.go
+++ b/doStats.go
@@ -5,9 +5,14 @@ package main
import (
"errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "slices"
"strings"
"go.wit.com/lib/cobol"
+ "go.wit.com/lib/config"
"go.wit.com/lib/env"
"go.wit.com/lib/protobuf/argvpb"
"go.wit.com/lib/protobuf/gitpb"
@@ -59,7 +64,7 @@ func doStats(cmd *StatsCmd) (string, error) {
func doStatsRepo(r *gitpb.Repo) (string, error) {
var allerr error
- pb, err := r.LoadStats()
+ pb, err := r.LoadStats("origin")
if err == nil {
log.Info("LoadStats() ok", pb.Filename)
} else {
@@ -242,3 +247,193 @@ func safeDelete(r *gitpb.Repo, deleteHash string, keepHash string) error {
return log.Errorf("NOT SAFE")
}
+
+// /tmp/go-nsupdate$ git ls-remote
+// From [email protected]:SpComb/go-nsupdate.git
+// d65f28d10991354b3af0168001a4beea6b8242f9 HEAD
+// d65f28d10991354b3af0168001a4beea6b8242f9 refs/heads/master
+// fb04ebe13a16c01e1a7eb3892a0aca8c6db96fa0 refs/pull/3/head
+// d774220311b2d44c770e7431ec663c8875488a1e refs/pull/6/head
+// fefb9ea80745893a2203576bdc2872d33e539064 refs/pull/7/head
+// c09c90d0a931888862262a6ed3753eed0af4ddca refs/pull/8/head
+
+// the correct syntax for
+// git log -n 8 --format=%H%00%ae%00%as%00%s origin/HEAD
+func updateStats(r *gitpb.Repo, pb *gitpb.Stats, remoteName string) (int, error) {
+ var allerr error
+ var counter int
+ cmd := []string{"git", "log", "-n", "100", makeFmts(), remoteName} // must use 'master' as queried from the git server
+ // cmd := []string{"git", "log", "-n", "100", makeFmts(), "origin/HEAD"} // HEAD is _NOT_ always set
+ if env.True("stats") {
+ log.Info("Run:", cmd)
+ }
+ cmdout := r.Run(cmd)
+ for i, line := range cmdout.Stdout {
+ parts := strings.Split(line, standardSeperator)
+ hash := parts[0]
+ if len(parts) < 2 {
+ log.Printf("Repo: %s\n", r.FullPath)
+ log.Printf("CMD: %v\n", cmd)
+ log.Printf("LINE:%8.8s %2d %v\n", hash, i, parts[1:])
+ }
+ if env.True("stats") {
+ log.Printf("LINE:%8.8s %2d %v\n", hash, i, parts[1:])
+ }
+ found := pb.FindByHash(hash)
+ if found != nil {
+ // already have this hash
+ continue
+ }
+ counter += 1
+ astat := new(gitpb.Stat)
+ astat.Hash = hash
+ ctime, err := cobol.GetTime(parts[2])
+ allerr = errors.Join(allerr, err)
+ astat.Ctime = timestamppb.New(*ctime)
+ astat.Subject = parts[4]
+ astat.Type = gitpb.Stat_REMOTE
+ pb.Append(astat)
+ }
+ return counter, allerr
+}
+
+/*
+func lookupRefs(r *gitpb.Repo, remoteRefs *gitpb.Stats) error {
+ rname := remoteRefs.Name()
+ for stat := range remoteRefs.IterAll() {
+ log.Info("remote", rname, stat.Name)
+ }
+}
+*/
+
+// returns err if anything changes or anything is wrong (todo: should these be different?)
+func makeRefs(r *gitpb.Repo, remoteName string) error {
+ var counter int // inc if anything changes
+ fullname := filepath.Join(r.FullPath, ".git", remoteName+".refs.pb")
+ stats := gitpb.NewStats()
+ stats.Filename = fullname
+ err := config.ForceCreatePB(stats)
+ if err != nil {
+ return err
+ }
+
+ var last *gitpb.Stat
+ for stat := range stats.IterAll() {
+ if last == nil {
+ last = stat
+ continue
+ }
+ if strings.Compare(stat.Hash, last.Hash) > 0 {
+ log.Info("Compare worked", stat.Hash, last.Hash, r.FullPath)
+ } else {
+ log.Info("Compare failed", stat.Hash, last.Hash, r.FullPath)
+ os.Remove(stats.Filename)
+ return errors.New("out of order")
+ }
+ if strings.Compare(stat.Hash, last.Hash) == 0 {
+ panic("was match")
+ }
+ last = stat
+ }
+
+ // cmd := []string{"git", "show-ref"} // must use 'master' as queried from the git server
+ cmd := []string{"git", "ls-remote", remoteName} // must use 'master' as queried from the git server // GO has 250k remote refs
+ // cmd := []string{"git", "log", "-n", "100", makeFmts(), "origin/HEAD"} // HEAD is _NOT_ always set
+ 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 done int
+ var allnew []*gitpb.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(gitpb.Stat)
+ newstat.Type = gitpb.Stat_REMOTE
+ newstat.Hash = parts[0]
+ newstat.Name = parts[1]
+ if stats.Len() == 0 {
+ stats.Append(newstat)
+ continue
+ }
+ n, found := slices.BinarySearchFunc(stats.Stats, newstat, func(a, b *gitpb.Stat) int {
+ return strings.Compare(a.Hash, b.Hash)
+ })
+ _ = n
+
+ if n > stats.Len() {
+ log.Info("WTF n,len =", n, stats.Len())
+ stats.Append(newstat)
+ continue
+ }
+ if n-1 < 0 {
+ log.Info("WTF n,len =", n, stats.Len())
+ continue
+ }
+
+ testfind := stats.Stats[n-1]
+ if testfind.Hash == newstat.Hash {
+ done += 1
+ log.Info(counter, ticker, "N WAS RIGHT", n, found, newstat.Hash, "HASH", testfind.Hash)
+ panic("fucknuts")
+ }
+ if found {
+ done += 1
+ teststat := stats.FindByHash(newstat.Hash)
+ if teststat == nil {
+ // log.Info(counter, ticker, "FOUND TEST STAT:", n, found, "HASH", newstat)
+ log.Printf("FOUND:%v %d/%d/%d %s %v\n", parts, done, counter, len(cmdout.Stdout), r.FullPath, teststat)
+ panic("fucknuts")
+ }
+ continue
+ } else {
+ teststat := stats.FindByHash(newstat.Hash)
+ if teststat != nil {
+ log.Printf("NOT FOUND:%v %d/%d/%d %s %v\n", parts, done, counter, len(cmdout.Stdout), r.FullPath, teststat)
+ // log.Info(counter, ticker, "NOT FOUND TEST STAT:", n, found, teststat, "HASH", newstat)
+ panic("fucknuts")
+ }
+ }
+ allnew = append(allnew, newstat)
+
+ ticker += 1
+ if ticker > 1000 {
+ log.Printf("TICKER:%v %d/%d/%d %s\n", parts, done, counter, len(cmdout.Stdout), r.FullPath)
+ ticker = 0
+ break
+ /*
+ stats.Stats = append(stats.Stats, allnew...)
+ stats.SortByHash()
+ stats.Save()
+ log.Printf("TICKER:%v %d/%d/%d %s\n", parts, done, counter, len(cmdout.Stdout), r.FullPath)
+ return nil
+ */
+ }
+ }
+ if counter > 0 {
+ stats.Stats = append(stats.Stats, allnew...)
+ stats.SortByHash()
+ stats.Save()
+ return errors.New(fmt.Sprintf("len(%d), ticker(%d) counter(%d) refs changed", stats.Len(), ticker, counter))
+ }
+ return nil
+}
diff --git a/doVerifyNamespace.go b/doVerifyNamespace.go
index cc42108..7f1d57f 100644
--- a/doVerifyNamespace.go
+++ b/doVerifyNamespace.go
@@ -13,6 +13,18 @@ import (
"go.wit.com/log"
)
+// checks to see if the r.Namespace seems right
+func doVerifyNamespace() (string, error) {
+ fixed := me.forge.RunOnRepos(me.forge.Repos, doCleanNamespace)
+ if fixed.Len() != 0 {
+ fixed = fixed.SortActual()
+ footer := me.forge.PrintDefaultTB(fixed)
+ me.forge.Repos.SaveVerbose()
+ return "changed namespaces: " + footer, nil
+ }
+ return "no namespaces changed", nil
+}
+
func doCleanNamespace(r *gitpb.Repo) error {
// check for GO repos
gowork := env.Get("gopath")
@@ -33,14 +45,19 @@ func doCleanNamespace(r *gitpb.Repo) error {
return errors.Join(errors.New(s), err)
}
-// checks to see if the r.Namespace seems right
-func doVerifyNamespace() (string, error) {
- fixed := me.forge.RunOnRepos(me.forge.Repos, doCleanNamespace)
- if fixed.Len() != 0 {
- fixed = fixed.SortActual()
- footer := me.forge.PrintDefaultTB(fixed)
- me.forge.Repos.SaveVerbose()
- return "changed namespaces: " + footer, nil
+func doGitConfig(r *gitpb.Repo) error {
+ if r.Config == nil {
+ return errors.New(".git/config is nil")
}
- return "no namespaces changed", nil
+
+ for _, rmote := range r.Config.Remotes {
+ if err := makeRefs(r, rmote.Name); err != nil {
+ return err
+ }
+ }
+
+ // err = errors.New("namepace changed")
+ // s := fmt.Sprintf("old(%s), new(%s)", r.Namespace, newpath)
+ // return errors.Join(errors.New(s), err)
+ return nil
}