package forgepb import ( "os" "path/filepath" "time" "go.wit.com/lib/gui/shell" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) var ErrorNotAllReposOnMaster error = log.Errorf("not all repos on are on the master branch") var ErrorNotAllReposOnDevel error = log.Errorf("not all repos on are on the devel branch") var ErrorNotAllReposOnUser error = log.Errorf("not all repos on are on the user branch") func (f *Forge) IsEverythingOnMaster() (int, int, int, error) { var total int var count int var nope int // first make sure every repo is on the master branch for repo := range f.Repos.IterAll() { total += 1 if repo.GetMasterBranchName() == repo.GetCurrentBranchName() { count += 1 } else { nope += 1 } } if total != count { // log.Info(ErrorNotAllReposOnMaster) return total, count, nope, ErrorNotAllReposOnMaster } return total, count, nope, nil } func (f *Forge) IsEverythingOnDevel() (int, int, int, error) { var total int var count int var nope int // first make sure every repo is on the master branch for repo := range f.Repos.IterAll() { total += 1 if repo.GetDevelBranchName() == repo.GetCurrentBranchName() { count += 1 } else { nope += 1 } } if total != count { return total, count, nope, ErrorNotAllReposOnDevel } return total, count, nope, nil } func (f *Forge) IsEverythingOnUser() (int, int, int, error) { var total int var count int var nope int // first make sure every repo is on the master branch for repo := range f.Repos.IterAll() { total += 1 if repo.GetCurrentBranchName() == repo.GetUserBranchName() { count += 1 } else { nope += 1 } } if total != count { return total, count, nope, ErrorNotAllReposOnUser } return total, count, nope, nil } // trys to figure out if there is still something to update func (f *Forge) DoAllCheckoutMaster() error { now := time.Now() f.RillFuncError(rillCheckoutMaster) count := f.RillReload() if count != 0 { f.ConfigSave() } total, count, nope, err := f.IsEverythingOnMaster() log.Printf("Master branch check. %d total repos. (%d ok) (%d not on master branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now))) if err != nil { // display all repos not on master found := new(gitpb.Repos) all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() if repo.GetCurrentBranchName() != repo.GetMasterBranchName() { found.Append(repo) } } f.PrintHumanTable(found) log.Printf("There are %d repos that are NOT on the master branch\n", found.Len()) return err } return nil } func rillCheckoutMaster(repo *gitpb.Repo) error { if repo.IsDirty() { // never do dirty repos return nil } // 'giterr' means something is very wrong with this repo if repo.GetMasterVersion() == "giterr" { repo.CheckoutMaster() log.Info("master == giterr. BAD REPO", repo.GetFullPath()) log.Info("master == giterr. BAD REPO", repo.GetFullPath()) log.Info("master == giterr. BAD REPO", repo.GetFullPath()) cmd := []string{"git", "checkout", "main"} // todo: figure out main repo.RunVerbose(cmd) os.Exit(-1) return nil } if repo.GetCurrentBranchName() == repo.GetMasterBranchName() { // repo is already on master return nil } repo.CheckoutMaster() return nil } func rillCheckoutUser(repo *gitpb.Repo) error { if repo.IsDirty() { // never do dirty repos return nil } if repo.GetCurrentBranchName() == repo.GetMasterBranchName() { // repo is already on devel branch. have to move them there first for now // return repo.CheckoutDevel() } if repo.GetCurrentBranchName() == repo.GetUserBranchName() { // repo is already on user branch return nil } if err := repo.CheckoutUser(); err != nil { log.Info(repo.GetFullPath(), err) return err } return nil } // trys to figure out if there is still something to update func (f *Forge) DoAllCheckoutUser(force bool) error { now := time.Now() if force { log.Info("going to force create user branches") if err := f.makeUserBranches(); err != nil { return err } } f.RillFuncError(rillCheckoutUser) count := f.RillReload() if count != 0 { f.ConfigSave() } total, count, nope, err := f.IsEverythingOnUser() log.Printf("User branch check. %d total repos. (%d ok) (%d not on user branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now))) if err != nil { // display all repos not on user found := new(gitpb.Repos) all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() if repo.GetCurrentBranchName() != repo.GetUserBranchName() { found.Append(repo) } } f.PrintHumanTable(found) log.Printf("There are %d repos that are NOT on the user branch\n", found.Len()) return err } return nil } func (f *Forge) makeUserBranches() error { all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() branch := repo.GetUserBranchName() if repo.Exists(filepath.Join(".git/refs/heads", branch)) { continue } if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch)) { cmd := []string{"git", "checkout", branch} repo.RunVerbose(cmd) continue } cmd := []string{"git", "branch", branch} repo.RunVerbose(cmd) cmd = []string{"git", "checkout", branch} repo.RunVerbose(cmd) } return nil } func testReload(repo *gitpb.Repo) error { if !repo.DidRepoChange() { return nil } repo.Reload() return log.Errorf("repo changed") } func (f *Forge) DoAllCheckoutDevelNew(force bool) error { f.makeDevelBranches() // first run git checkout stats := f.RillFuncError(rillCheckoutDevel) for path, stat := range stats { dur := stat.End.Sub(stat.Start) if dur > 1*time.Second { log.Infof("%s git checkout took a long time (%s)\n", path, shell.FormatDuration(dur)) } if stat.Err == nil { // there was no error continue } // didn't change to devel } var counter int // recreate the repo protobuf stats = f.RillFuncError(testReload) for path, stat := range stats { dur := stat.End.Sub(stat.Start) if dur > 1*time.Second { log.Infof("%s # Reload took a long time (%s)\n", path, shell.FormatDuration(dur)) } if stat.Err == nil { // repo didn't reload continue } // repo reloaded counter += 1 } log.Info("reloaded", counter, "repos") f.configSave = true return nil } // is every repo on the devel branch? func (f *Forge) DoAllCheckoutDevel(force bool) error { now := time.Now() if force { log.Info("going to force create devel branches") f.makeDevelBranches() } log.Info("going to rill:") f.RillFuncError(rillCheckoutDevel) count := f.RillReload() if count != 0 { f.ConfigSave() } total, count, nope, err := f.IsEverythingOnDevel() log.Printf("Devel branch check. %d total repos. (%d ok) (%d not on devel branch) (%s)\n", total, count, nope, shell.FormatDuration(time.Since(now))) if err != nil { // display all repos not on user found := new(gitpb.Repos) all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() if repo.GetCurrentBranchName() != repo.GetDevelBranchName() { found.Append(repo) } } f.PrintHumanTable(found) log.Printf("There are %d repos that are NOT on the devel branch\n", found.Len()) return err } return nil } func (f *Forge) makeDevelBranches() error { all := f.Repos.SortByFullPath() for all.Scan() { repo := all.Next() branch := repo.GetDevelBranchName() if repo.Exists(filepath.Join(".git/refs/heads", branch)) { continue } if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch)) { cmd := []string{"git", "checkout", branch} repo.RunVerbose(cmd) continue } cmd := []string{"git", "branch", branch} repo.RunVerbose(cmd) cmd = []string{"git", "checkout", branch} repo.RunVerbose(cmd) } return nil } func rillCheckoutDevel(repo *gitpb.Repo) error { if repo.IsDirty() { // never do dirty repos return nil } if repo.GetCurrentBranchName() == repo.GetDevelBranchName() { // repo is already on devel branch return nil } repo.CheckoutDevel() return nil }