// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main import ( "strings" "go.wit.com/lib/protobuf/gitpb" "go.wit.com/log" ) // this populates a slice of protobuf records representing each git repo // var found []*gitpb.Repo // // so, it makes a subset of repos that are then used performing actions on // // by default, it adds every repo func doFind() *gitpb.Repos { if argv.Show == nil { return findAll() } if argv.Show.Repo.Mine { return findMine() } if argv.Show.Dirty != nil { return me.forge.FindDirty() } return findAll() } func findRepos() *gitpb.Repos { if argv.Show == nil { return findMine() } if argv.Show.Dirty != nil { return me.forge.FindDirty() } if argv.Show.Repo == nil { return findAll() } if argv.Show.Repo.All { return findAll() } if argv.Show.Repo.Private { return findPrivate() } if argv.Show.Repo.Mine { return findMine() } if argv.Show.Repo.Favorites { return findFavorites() } if argv.Show.Repo.User { return findUser() } return findAll() } func findPrivate() *gitpb.Repos { found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { if me.forge.Config.IsPrivate(repo.Namespace) { found.AppendByFullPath(repo) } } return found } // finds repos that are writable func findMine() *gitpb.Repos { found := gitpb.NewRepos() // log.Printf("get mine %s\n", me.forge.GetGoSrc()) for repo := range me.forge.Repos.IterByFullPath() { if me.forge.Config.IsWritable(repo.Namespace) { found.AppendByFullPath(repo) } } return found } // finds repos the user has marked as favorites in the forge .config func findFavorites() *gitpb.Repos { found := gitpb.NewRepos() // log.Printf("get favorites %s\n", me.forge.GetGoSrc()) for repo := range me.forge.Repos.IterByFullPath() { if me.forge.Config.IsFavorite(repo.Namespace) { found.AppendByFullPath(repo) } } return found } func findAll() *gitpb.Repos { found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { found.AppendByFullPath(repo) } return found } func find50() *gitpb.Repos { count := 0 found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { found.AppendByFullPath(repo) if count > 50 { return found } count += 1 } return found } func findUser() *gitpb.Repos { found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { if repo.GetCurrentBranchName() == repo.GetUserBranchName() { found.AppendByFullPath(repo) } } return found } func findPublishable() *gitpb.Repos { found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { if repo.GetTargetVersion() == "" { continue } found.AppendByFullPath(repo) } return found } func findReposWithPatches() *gitpb.Repos { found := gitpb.NewRepos() for repo := range me.forge.Repos.IterByFullPath() { if repo.IsDirty() { repo.State = "dirty" // always add dirty branches found.AppendByFullPath(repo) continue } if repo.GetUserVersion() == "" || repo.GetUserVersion() == "uerr" { // skip anything without a user branch continue } if repo.GetUserVersion() != repo.GetDevelVersion() { repo.State = "userNEdevel" found.AppendByFullPath(repo) continue } // ignore read-only repos for checks below here if me.forge.Config.IsReadOnly(repo.Namespace) { continue } // show anything that differs between 'devel' & 'master' branches if repo.GetDevelVersion() != repo.GetMasterVersion() { if !strings.HasPrefix(repo.Namespace, "go.wit.com") { // todo: make this a config setting continue } repo.State = "devVSmaster" found.AppendByFullPath(repo) continue } // this is an old test to see if the current 'last tag' is accurate and should be removed if repo.GetLastTag() != repo.GetMasterVersion() { // todo: make this a config setting if strings.HasPrefix(repo.Namespace, "go.wit.com") { repo.State = "tagVSmaster" found.AppendByFullPath(repo) repo.FindLastTag() } continue } } return found } func cloneReposWithPatches() *gitpb.Repos { found := gitpb.NewRepos() var stop int for repo := range me.forge.Repos.IterByFullPath() { if repo.IsDirty() { // always add dirty branches r := found.Clone(repo) r.State = "is dirty" repo.State = "is dirty" continue } if repo.GetUserVersion() == "" { // skip anything without a user branch THEBRANCH := repo.GetUserBranchName() if repo.IsLocalBranch(THEBRANCH) { continue } if repo.IsRemoteBranch(THEBRANCH) { log.Info(repo.FullPath, "BRANCH IS REMOTE:", THEBRANCH) } if repo.IsLocalBranchVerbose(THEBRANCH) { log.Info(repo.FullPath, "BRANCH IS LOCAL:", THEBRANCH) // everthing is actually normal continue } else { log.Info(repo.FullPath, "BRANCH IS NOT LOCAL:", THEBRANCH) repo.RunVerbose([]string{"bash", "-c", "git show-ref |grep -v tags"}) } stop += 1 if stop < 5 { for t := range repo.Tags.IterAll() { log.Info("pb thinks it has:", repo.Namespace, t.Refname) } } else { if argv.Fix { log.Info("curbranch is doesn't exist. this'll cause all sorts of problems", THEBRANCH, repo.FullPath) log.Info("checking out with force", repo.FullPath) repo.CheckoutForce() repo.RunVerbose([]string{"git", "branch"}) repo.ReloadForce() me.forge.Repos.SaveSafe() } panic("stop. run 'forge fixer porcelein' and see what happens") } // no user branch r := found.Clone(repo) r.State = log.Sprintf("no br '%s'", THEBRANCH) continue } if repo.GetUserVersion() == "uerr" { // skip anything without a user branch r := found.Clone(repo) r.State = "user == 'uerr'" continue } if repo.GetUserVersion() != repo.GetDevelVersion() { r := found.Clone(repo) r.State = "user != dev" continue } // ignore read-only repos for checks below here if me.forge.Config.IsReadOnly(repo.Namespace) { continue } // show anything that differs between 'devel' & 'master' branches if repo.GetDevelVersion() != repo.GetMasterVersion() { // this repo.State code isn't great, but it got me here quickly // I'll defend my code by saying it's faster for me if I do dumb things // sometimes and fix them later. Probably some employee will have to // fix this. if that is the case I owe you lunch. or stock options // log.Info("repo state", repo.FullPath, repo.State) r := found.Clone(repo) r.State = "DEVEL behind MASTER" continue } // this is an old test to see if the current 'last tag' is accurate and should be removed if repo.GetLastTag() != repo.GetMasterVersion() { repo.ReloadForce() r := found.Clone(repo) r.FindLastTag() r.State = "lasttag mismatch" continue } } return found } // Shows repos that are: // - git dirty repos // - repos with 'user' branch patches not in 'devel' branch // - repos with awaiting master branch verions // // return true if any are found func findWorkRepos() *gitpb.Repos { // always run dirty first me.forge.CheckDirtyQuiet() // if no option is given to patch, list out the // repos that have patches ready in them found := findReposWithPatches() return found }