// Copyright 2025 WIT.COM Inc Licensed GPL 3.0 package forgepb import ( "fmt" "path/filepath" "go.wit.com/lib/gui/shell" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) // you can replace all of COBOL with this amount of GO // ah yes, COBOL. what an ancient throwback. for those that know // then you know exactly what is in this file. For those that don't, here it is: // All this does is output human readable text formatted to be viewable on // a console with a fixed with font. AKA: a typerwriter. Which is exactly // what COBOL did in the 1970's (60s? notsure) And the 80s. // So, you want to dump out stuff on the console. Let's see. Something like /* forge --favorites go.wit.com/apps/myapp v0.2.0 (installed) go.wit.com/lib/somethingfun v0.0.7 (not downloaded) */ // anyway, you get the idea. This is also called COBOL because it does on // thing and truncates every line output to the columns you see with stty -a // my monitor is huge, so it's not going to work at 80x24. 160x48 is better // actually, I'd predict some of these will probably end up 240 wide // long live good eyesight and 4K monitors! func (f *Forge) PrintHumanTable(allr *gitpb.Repos) { log.DaemonMode(true) var count int // print the header args := []string{"repopath", "cur br", "age", "master", "devel", "user", "curver", "lasttag", "next", "repo type"} sizes := []int{40, 12, 6, 12, 16, 16, 16, 12, 12, 8} log.Info(standardTableSize10(sizes, args)) all := allr.SortByFullPath() for all.Scan() { repo := all.Next() f.printRepoToTable(repo, sizes, false) count += 1 } log.Info("Total git repositories:", count) } func (f *Forge) PrintHumanTableFull(allr *gitpb.Repos) { log.DaemonMode(true) var count int // print the header args := []string{"cur br", "age", "master", "devel", "user", "curver", "lasttag", "next", "repo type", "repopath"} sizes := []int{12, 6, 12, 16, 16, 16, 12, 12, 8, 0} log.Info(standardTableSize10(sizes, args)) all := allr.SortByFullPath() for all.Scan() { repo := all.Next() f.printRepoToTable(repo, sizes, true) count += 1 } log.Info("Total git repositories:", count) } // also shows which files are dirty func (f *Forge) PrintHumanTableDirty(allr *gitpb.Repos) { log.DaemonMode(true) var count int // print the header args := []string{"repopath", "cur br", "age", "master", "devel", "user", "curver", "lasttag", "next", "repo type"} sizes := []int{40, 12, 6, 12, 16, 16, 16, 12, 12, 8} log.Info(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("\t", line) } } var mver string = repo.GetMasterVersion() repo.Tags.GetAge(mver) count += 1 } log.Info("Total git repositories:", count) } func standardTable5(arg1, arg2, arg3, arg4, arg5 string) string { len1 := 40 len2 := 12 len3 := 12 len4 := 16 len5 := 8 var s string if len(arg1) > len1 { arg1 = arg1[:len1] } s = "%-" + fmt.Sprintf("%d", len1) + "s " if len(arg2) > len2 { arg2 = arg2[:len2] } s += "%-" + fmt.Sprintf("%d", len2) + "s " if len(arg3) > len3 { arg3 = arg3[:len3] } s += "%-" + fmt.Sprintf("%d", len3) + "s " if len(arg4) > len4 { arg4 = arg4[:len4] } s += "%-" + fmt.Sprintf("%d", len4) + "s " if len(arg5) > len5 { arg5 = arg5[:len5] } s += "%-" + fmt.Sprintf("%d", len5) + "s" return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5) } /* func standardTable10(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10 string) string { args := []string{arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10} sizes := []int{40, 12, 6, 12, 16, 16, 16, 12, 12, 8} return standardTableSize10(sizes, args) } */ func standardTableSize10(sizes []int, args []string) string { var s string for i, si := range sizes { if si == 0 { s += "%-s " } else { s += "%-" + fmt.Sprintf("%d", si) + "s " if len(args[i]) > sizes[i] { args[i] = args[i][:sizes[i]] } } } // there must be a better syntax for this arg1 := args[0] arg2 := args[1] arg3 := args[2] arg4 := args[3] arg5 := args[4] arg6 := args[5] arg7 := args[6] arg8 := args[7] arg9 := args[8] arg10 := args[9] return fmt.Sprintf(s, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) // return fmt.Sprintf(s, args) } 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 uhort string = repo.GetUserVersion() if uhort == "uerr" { // blank these out uhort = "" } var lasttag string = repo.GetLastTag() var thort string = repo.GetTargetVersion() var chort string = repo.GetCurrentBranchVersion() var cname string = repo.GetCurrentBranchName() var gopath string = repo.GetGoPath() var rtype string = repo.GetRepoType() // 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 = "" end += "(dirty) " } var args []string if full { args = []string{cname, age, mhort, dhort, uhort, chort, lasttag, thort, rtype, gopath} } else { args = []string{gopath, cname, age, mhort, dhort, uhort, chort, lasttag, thort, rtype} } start := 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(start, end) }