2025-01-18 15:50:06 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2025-01-19 02:37:04 -06:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"slices"
|
2025-01-18 15:50:06 -06:00
|
|
|
|
|
|
|
"go.wit.com/lib/protobuf/gitpb"
|
|
|
|
"go.wit.com/log"
|
|
|
|
)
|
|
|
|
|
2025-01-18 23:25:55 -06:00
|
|
|
var ErrorReposHasLocalBranches error = fmt.Errorf("repo still has local branches")
|
|
|
|
|
2025-01-18 15:50:06 -06:00
|
|
|
func doClean() error {
|
2025-01-18 23:25:55 -06:00
|
|
|
if err := IsEverythingOnMaster(); err != nil {
|
|
|
|
log.Info("Not all repos are on the master branch")
|
|
|
|
// return err
|
|
|
|
}
|
|
|
|
|
2025-01-18 15:50:06 -06:00
|
|
|
all := me.forge.Repos.SortByFullPath()
|
|
|
|
for all.Scan() {
|
|
|
|
repo := all.Next()
|
2025-01-18 23:25:55 -06:00
|
|
|
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
2025-01-19 00:35:58 -06:00
|
|
|
// skip this while in devel
|
|
|
|
// continue
|
2025-01-18 23:25:55 -06:00
|
|
|
}
|
2025-01-18 15:50:06 -06:00
|
|
|
if err := doCleanRepo(repo); err != nil {
|
2025-01-18 23:25:55 -06:00
|
|
|
badRepoExit(repo, err)
|
2025-01-18 15:50:06 -06:00
|
|
|
}
|
|
|
|
}
|
2025-01-18 23:25:55 -06:00
|
|
|
log.Info("All repos on the master branch are clean")
|
2025-01-18 15:50:06 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2025-01-18 23:25:55 -06:00
|
|
|
// removes all local branches
|
2025-01-18 15:50:06 -06:00
|
|
|
func doCleanRepo(repo *gitpb.Repo) error {
|
2025-01-18 23:25:55 -06:00
|
|
|
var hasLocal bool
|
2025-01-19 00:35:58 -06:00
|
|
|
if argv.Verbose {
|
|
|
|
log.Info("Cleaning:", repo.GetGoPath())
|
|
|
|
}
|
2025-01-18 15:50:06 -06:00
|
|
|
if repo.GitConfig == nil {
|
|
|
|
return fmt.Errorf("GitConfig == nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, l := range repo.GitConfig.Local {
|
|
|
|
log.Info("\tlocal branch name:", l.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, b := range repo.GitConfig.Branches {
|
2025-01-19 00:35:58 -06:00
|
|
|
if b.Name == "" {
|
|
|
|
b.Name = name
|
|
|
|
}
|
2025-01-18 23:25:55 -06:00
|
|
|
if name == repo.GetMasterBranchName() {
|
2025-01-19 00:35:58 -06:00
|
|
|
// never delete the master branch
|
|
|
|
// todo: make sure the master branch is in sync with remote master
|
2025-01-18 23:25:55 -06:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
hasLocal = true
|
2025-01-19 00:35:58 -06:00
|
|
|
if name == repo.GetUserBranchName() {
|
|
|
|
if err := doCleanUserBranch(repo, b); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if name == repo.GetDevelBranchName() {
|
|
|
|
if err := doCleanDevelBranch(repo, b); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
log.Info("\tlocal branch name unknown:", name, b.Merge, b.Remote)
|
2025-01-18 15:50:06 -06:00
|
|
|
}
|
2025-01-18 23:25:55 -06:00
|
|
|
if hasLocal {
|
|
|
|
return ErrorReposHasLocalBranches
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func verifyLocalBranchIsMerged(repo *gitpb.Repo, branch *gitpb.GitBranch) error {
|
2025-01-18 15:50:06 -06:00
|
|
|
return nil
|
|
|
|
}
|
2025-01-19 00:35:58 -06:00
|
|
|
|
|
|
|
func doCleanDevelBranch(repo *gitpb.Repo, branch *gitpb.GitBranch) error {
|
|
|
|
log.Printf("\tDo something %s on branch name:%s merge:%s remote:%s\n", repo.GetGoPath(), branch.Name, branch.Merge, branch.Remote)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func doCleanUserBranch(repo *gitpb.Repo, branch *gitpb.GitBranch) error {
|
|
|
|
if branch.Name != repo.GetUserBranchName() {
|
|
|
|
return fmt.Errorf("repo %s was not user branch %s", repo.GetGoPath(), branch.Name)
|
|
|
|
}
|
2025-01-19 02:37:04 -06:00
|
|
|
/*
|
|
|
|
if bran == repo.GetUserBranchName() {
|
|
|
|
log.Info("The user branch also has a remote branch", repo.CurrentTag.Refname)
|
|
|
|
log.Info("TODO: verify the remote branch is out of date", repo.CurrentTag.Refname)
|
|
|
|
log.Info("TODO: delete the remote branch", repo.CurrentTag.Refname)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
if !repo.Exists(filepath.Join(".git/refs/heads", branch.Name)) {
|
|
|
|
err := fmt.Errorf("BAD FORGE LOGIC. DELETE REPO %s", repo.GetGoPath())
|
|
|
|
log.Warn(err)
|
|
|
|
me.forge.Repos.Repos = slices.DeleteFunc(me.forge.Repos.Repos, func(r *gitpb.Repo) bool {
|
|
|
|
if repo.GetGoPath() == r.GetGoPath() {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
// me.forge.Repos.Delete(repo)
|
|
|
|
me.forge.ConfigSave()
|
|
|
|
os.Exit(0)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if repo.Exists(filepath.Join(".git/refs/remotes/origin", branch.Name)) {
|
|
|
|
log.Info("why is this non-localonly branch a problem?", branch.Name)
|
|
|
|
repo.RunVerbose([]string{"ls", "-l", ".git/refs/remotes/origin"})
|
|
|
|
repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/remotes/origin", branch.Name)})
|
|
|
|
repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/heads", branch.Name)})
|
|
|
|
} else {
|
|
|
|
log.Info("why is this local only branch a problem?", branch.Name)
|
|
|
|
repo.RunVerbose([]string{"ls", "-l", ".git/refs/remotes/origin"})
|
|
|
|
r, err := repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/heads", branch.Name)})
|
|
|
|
if err == nil {
|
|
|
|
cmd := []string{"git", "show", "-s", "--format=\"%H %ae %as %s\"", r.Stdout[0]}
|
|
|
|
repo.RunVerbose(cmd)
|
|
|
|
log.Info(cmd)
|
|
|
|
}
|
|
|
|
if err := userToDevelRequiresGitPush(repo, branch.Name); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
log.Info("THIS USER BRANCH IS CLEAN TO DELETE", branch.Name)
|
|
|
|
if argv.Clean.Force != nil {
|
|
|
|
cmd := []string{"git", "branch", "-D", branch.Name}
|
|
|
|
_, err := repo.RunVerbose(cmd)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// return fmt.Errorf("%s repo.CurrentTag is not local: %s. Don't proceed yet", repo.GetGoPath(), repo.CurrentTag.Refname)
|
|
|
|
log.Printf("Do something %s on branch name:%s merge:%s remote:%s\n", repo.GetGoPath(), branch.Name, branch.Merge, branch.Remote)
|
2025-01-19 00:35:58 -06:00
|
|
|
return nil
|
|
|
|
}
|
2025-01-19 02:37:04 -06:00
|
|
|
|
|
|
|
func userToDevelRequiresGitPush(repo *gitpb.Repo, branchName string) error {
|
|
|
|
devel := repo.GetDevelBranchName()
|
|
|
|
b1 := countDiffObjects(repo, branchName, "origin/"+devel)
|
|
|
|
b2 := countDiffObjects(repo, "origin/"+devel, branchName)
|
|
|
|
log.Info("user vs devel count", b1, b2)
|
|
|
|
if b1 == 0 && b2 == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if b1 != 0 {
|
|
|
|
log.Info("user vs devel count b1 != 0, b2 ==", b1, b2)
|
|
|
|
log.Info("THIS MEANS THE LOCAL BRANCH NEEDS GIT PUSH TO ORIGIN BRANCH ==", b1)
|
|
|
|
// if argv.Examine.Fix != nil {
|
|
|
|
// return gitPushStrict(repo, branchName)
|
|
|
|
// }
|
|
|
|
return fmt.Errorf("user branch not clean to delete %d %d", b1, b2)
|
|
|
|
}
|
|
|
|
return fmt.Errorf("user branch not clean to delete. maybe it is? devel might be ahead of user branch. %d %d", b1, b2)
|
|
|
|
}
|