// Copyright 2025 WIT.COM Inc Licensed GPL 3.0 package forgepb import ( "path/filepath" "go.wit.com/lib/cobol" "go.wit.com/lib/gui/shell" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) // All this does is output human readable text formatted to be viewable on // a console with a fixed with font. AKA: a typerwriter func (f *Forge) PrintHumanTable(allr *gitpb.Repos) { log.DaemonMode(true) t := new(tally) // print the header args := []string{"namespace", "branch", "age", "user", "devel", "master", "", "lasttag", "next", "repo type"} sizes := []int{35, 9, 4, 13, 13, 13, 1, 12, 12, 8} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) all := allr.SortByFullPath() for all.Scan() { repo := all.Next() f.printRepoToTable(repo, sizes, false) tallyBranchTotals(t, repo) } log.Infof("Total repositories: %d (%d master) (%d devel) (%d user) (%d unknown)\n", t.total, t.master, t.devel, t.user, t.unknown) } func (f *Forge) PrintForgedTable(allr *gitpb.Repos) { log.DaemonMode(true) t := new(tally) // print the header args := []string{"namespace", "branch", "age", "master", "devel", "last tag", "", "", "", ""} sizes := []int{35, 9, 4, 13, 13, 13, 13, 12, 12, 8} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) all := allr.SortByFullPath() for all.Scan() { repo := all.Next() f.printForgedToTable(repo, sizes) tallyBranchTotals(t, repo) } log.Infof("Total repositories: %d (%d user) (%d devel) (%d master) (%d unknown)\n", t.total, t.user, t.devel, t.master, t.unknown) } func (f *Forge) PrintHumanTableFull(allr *gitpb.Repos) { log.DaemonMode(true) t := new(tally) // print the header args := []string{"branch", "age", "user", "devel", "master", "", "lasttag", "next", "repo type", "namespace"} sizes := []int{9, 4, 13, 13, 13, 1, 12, 12, 8, 0} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) all := allr.SortByFullPath() for all.Scan() { repo := all.Next() f.printRepoToTable(repo, sizes, true) tallyBranchTotals(t, repo) } log.Infof("Total repositories: %d (%d user) (%d devel) (%d master) (%d unknown)\n", t.total, t.user, t.devel, t.master, t.unknown) } // also shows which files are dirty func (f *Forge) PrintHumanTableDirty(allr *gitpb.Repos) { log.DaemonMode(true) t := new(tally) // print the header args := []string{"namespace", "branch", "age", "user", "devel", "master", "", "lasttag", "next", "repo type"} sizes := []int{35, 9, 4, 13, 13, 13, 1, 12, 12, 8} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) for repo := range allr.IterAll() { f.printRepoToTable(repo, sizes, false) if len(repo.DirtyList) != 0 { for _, line := range repo.DirtyList { log.Info(cobol.TerminalChomp("\t" + line)) } } var mver string = repo.GetMasterVersion() repo.Tags.GetAge(mver) tallyBranchTotals(t, repo) } log.Infof("Total repositories: %d (%d user) (%d devel) (%d master) (%d unknown)\n", t.total, t.user, t.devel, t.master, t.unknown) } // used to count which repos are on which branches (master/main, devel, user) type tally struct { total int master int devel int user int unknown int } func tallyBranchTotals(t *tally, repo *gitpb.Repo) { t.total += 1 if repo.GetCurrentBranchName() == repo.GetMasterBranchName() { t.master += 1 return } if repo.GetCurrentBranchName() == repo.GetDevelBranchName() { t.devel += 1 return } if repo.GetCurrentBranchName() == repo.GetUserBranchName() { t.user += 1 return } log.Printf("unknown curr=%s user=%s devel=%s master=%s\n", repo.GetCurrentBranchName(), repo.GetUserBranchName(), repo.GetDevelBranchName(), repo.GetMasterBranchName()) t.unknown += 1 } func (f *Forge) printRepoToTable(repo *gitpb.Repo, sizes []int, full bool) { var end string // shortened version numbers var mhort string = repo.GetMasterVersion() var dhort string = repo.GetDevelVersion() var uver string = repo.GetUserVersion() if uver == "uerr" { // blank these out uver = "" } var lasttag string = repo.GetLastTag() var thort string = repo.GetTargetVersion() var chort string = "" // repo.GetCurrentBranchVersion() var cname string = repo.GetCurrentBranchName() var gopath string = repo.GetNamespace() if gopath == "" { gopath = repo.GetFullPath() } var rtype string = repo.GetRepoType() switch rtype { case "binary": rtype = "GO bin" case "library": rtype = "GO lib" case "protobuf": rtype = "GO pb" } if f.IsPrivate(repo) { rtype = "priv" } // ctime := repo.Tags.GetAge(mhort) // age := shell.FormatDuration(time.Since(ctime)) age := shell.FormatDuration(repo.BranchAge(cname)) if f.Config.IsReadOnly(repo.GetGoPath()) { // end += "(readonly) " } else { end += "(rw) " } if repo.IsDirty() { age = "" uver = "* " + uver end += "(dirty) " } var args []string if full { args = []string{cname, age, uver, dhort, mhort, chort, lasttag, thort, rtype, gopath} } else { args = []string{gopath, cname, age, uver, dhort, mhort, chort, lasttag, thort, rtype} } start := cobol.StandardTableSize10(sizes, args) if rtype == "protobuf" { if repo.GoInfo.GoBinary { end += "(binary) " } } if repo.GetMasterBranchName() != "master" && repo.GetMasterBranchName() != "main" { end += "(m:" + repo.GetMasterBranchName() + ") " } if repo.GetDevelBranchName() != "devel" { end += "(d:" + repo.GetDevelBranchName() + ") " } if repo.GetUserBranchName() != f.Config.Username { end += "(u:" + repo.GetUserBranchName() + ") " } debname := f.Config.DebName(repo.GetGoPath()) if debname != filepath.Base(gopath) { end += "(deb:" + debname + ") " } switch repo.GetState() { case "PERFECT": case "unchanged": case "dirty": case "unknown branches": if repo.CurrentTag == nil { end += "(" + repo.GetState() + ") " } else { end += "(unknown branch " + repo.CurrentTag.Refname + ") " } // end += "(invalid tag) " default: end += "(" + repo.GetState() + ") " } log.Info(cobol.TerminalChomp(start + " " + end)) } func (f *Forge) printForgedToTable(repo *gitpb.Repo, sizes []int) { var end string // shortened version numbers var mhort string = repo.GetMasterVersion() var dhort string = repo.GetDevelVersion() var lasttag string = repo.GetLastTag() var cname string = repo.GetCurrentBranchName() var ns string = repo.GetNamespace() age := shell.FormatDuration(repo.BranchAge(cname)) var args []string args = []string{ns, cname, age, mhort, dhort, lasttag, "", "", "", ""} start := cobol.StandardTableSize10(sizes, args) end += "todo" log.Info(cobol.TerminalChomp(start + " " + end)) } func (psets *Patchsets) PrintTable() { if psets == nil { return } log.DaemonMode(true) // print the header args := []string{"commit hash", "new hash", "", "", "name", "Repo Namespace", "", "", "", "", ""} sizes := []int{12, 12, 3, 3, 40, 80, 2, 2, 2, 2} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) var countCONTENTS int var countPARTS int for x, pset := range psets.GetPatchsets() { log.Info(pset.Uuid, pset.Name, pset.State) if pset.State == "DONE" { // old patchset continue } cId := log.Sprintf("%d", x) countCONTENTS += 1 for i, p := range pset.Patches.GetPatches() { var args []string partId := log.Sprintf("%d", i) _, fname := filepath.Split(p.GetFilename()) args = []string{p.CommitHash, p.NewHash, cId, partId, fname, p.GetNamespace(), "", "", "", "", ""} start := cobol.StandardTableSize10(sizes, args) log.Info(cobol.TerminalChomp(start)) countPARTS += 1 } } log.Infof("Total Contents (%d) Parts (%d)\n", countCONTENTS, countPARTS) } func (patches *Patches) PrintTable() { if patches == nil { return } log.DaemonMode(true) // print the header args := []string{"commit hash", "new hash", "", "", "name", "Repo Namespace", "", "", "", "", ""} sizes := []int{12, 12, 3, 3, 40, 80, 2, 2, 2, 2} log.Info(cobol.TerminalChomp(cobol.StandardTableSize10(sizes, args))) var countPARTS int for x, p := range patches.GetPatches() { var args []string partId := log.Sprintf("%d", x) _, fname := filepath.Split(p.GetFilename()) args = []string{p.CommitHash, p.NewHash, partId, fname, p.GetNamespace(), "", "", "", "", ""} start := cobol.StandardTableSize10(sizes, args) log.Info(cobol.TerminalChomp(start)) countPARTS += 1 } log.Infof("Total Patches (%d)\n", countPARTS) }