Skip to content

Commit

Permalink
Delete merged branches that have been checked out (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
seachicken authored Jan 30, 2022
1 parent a73502a commit 6b42a8a
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 63 deletions.
40 changes: 32 additions & 8 deletions connmock/stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,35 +61,35 @@ func (s *Stub) CheckRepos(err error, conf *Conf) *Stub {
return s
}

func (s *Stub) GetRepoNames(path string, err error, conf *Conf) *Stub {
func (s *Stub) GetRepoNames(filename string, err error, conf *Conf) *Stub {
s.t.Helper()
configure(
s.Conn.
EXPECT().
GetRepoNames().
Return(s.readFile("gh", "repo", path), err),
Return(s.readFile("gh", "repo", filename), err),
conf,
)
return s
}

func (s *Stub) GetBranchNames(name string, err error, conf *Conf) *Stub {
func (s *Stub) GetBranchNames(filename string, err error, conf *Conf) *Stub {
s.t.Helper()
configure(
s.Conn.EXPECT().
GetBranchNames().
Return(s.readFile("git", "branch", name), err),
Return(s.readFile("git", "branch", filename), err),
conf,
)
return s
}

func (s *Stub) GetAssociatedBranchNames(stubs []AssociatedBranchNamesStub, err error, conf *Conf) *Stub {
func (s *Stub) GetAssociatedRefNames(stubs []AssociatedBranchNamesStub, err error, conf *Conf) *Stub {
s.t.Helper()
for _, stub := range stubs {
configure(
s.Conn.EXPECT().
GetAssociatedBranchNames(stub.Oid).
GetAssociatedRefNames(stub.Oid).
Return(s.readFile("git", "abranch", stub.Filename), err),
conf,
)
Expand All @@ -110,13 +110,37 @@ func (s *Stub) GetLog(stubs []LogStub, err error, conf *Conf) *Stub {
return s
}

func (s *Stub) GetPullRequests(path string, err error, conf *Conf) *Stub {
func (s *Stub) GetPullRequests(filename string, err error, conf *Conf) *Stub {
s.t.Helper()
configure(
s.Conn.
EXPECT().
GetPullRequests(gomock.Any(), gomock.Any(), gomock.Any()).
Return(s.readFile("gh", "pr", path), err),
Return(s.readFile("gh", "pr", filename), err),
conf,
)
return s
}

func (s *Stub) GetUncommittedChanges(uncommittedChanges string, err error, conf *Conf) *Stub {
s.t.Helper()
configure(
s.Conn.
EXPECT().
GetUncommittedChanges().
Return(uncommittedChanges, err),
conf,
)
return s
}

func (s *Stub) CheckoutBranch(err error, conf *Conf) *Stub {
s.t.Helper()
configure(
s.Conn.
EXPECT().
CheckoutBranch(gomock.Any()).
Return("", err),
conf,
)
return s
Expand Down
2 changes: 1 addition & 1 deletion fixtures/git/abranch_issue1.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
issue1
refs/heads/issue1
2 changes: 2 additions & 0 deletions fixtures/git/abranch_issue1_origin-main.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
refs/heads/issue1
refs/remotes/origin/main
2 changes: 1 addition & 1 deletion fixtures/git/abranch_main.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
main
refs/heads/main
4 changes: 2 additions & 2 deletions fixtures/git/abranch_main_issue1.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
issue1
main
refs/heads/issue1
refs/heads/main
1 change: 1 addition & 0 deletions fixtures/git/branch_@issue1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*,issue1,356a192b7913b04c54574d18c28d46e6395428ab
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func runMain(check bool) {
sp.Start()
var fetchingErr error

branches, fetchingErr := GetBranches(conn)
branches, fetchingErr := GetBranches(conn, check)

sp.Stop()

Expand Down
50 changes: 40 additions & 10 deletions mocks/poi_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 83 additions & 12 deletions poi.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ type (
CheckRepos(hostname string, repoNames []string) error
GetRepoNames() (string, error)
GetBranchNames() (string, error)
GetLog(string) (string, error)
GetAssociatedBranchNames(string) (string, error)
GetLog(branchName string) (string, error)
GetAssociatedRefNames(oid string) (string, error)
GetPullRequests(hostname string, repoNames []string, queryHashes string) (string, error)
GetUncommittedChanges() (string, error)
CheckoutBranch(branchName string) (string, error)
DeleteBranches(branchNames []string) (string, error)
}

Expand Down Expand Up @@ -70,7 +72,7 @@ const (

var ErrNotFound = errors.New("not found")

func GetBranches(conn Connection) ([]Branch, error) {
func GetBranches(conn Connection, check bool) ([]Branch, error) {
var hostname string
var repoNames []string
var defaultBranchName string
Expand Down Expand Up @@ -109,7 +111,55 @@ func GetBranches(conn Connection) ([]Branch, error) {
}

branches = applyPullRequest(branches, prs)
branches = checkDeletion(branches)

uncommittedChanges, err := conn.GetUncommittedChanges()
if err != nil {
return nil, err
}

branches = checkDeletion(branches, uncommittedChanges)

needsCheckout := false
for _, branch := range branches {
if branch.Head && branch.State == Deletable {
needsCheckout = true
break
}
}

if needsCheckout {
result := []Branch{}

if !check {
_, err := conn.CheckoutBranch(defaultBranchName)
if err != nil {
return nil, err
}
}

if !branchNameExists(defaultBranchName, branches) {
result = append(result, Branch{
true, defaultBranchName,
[]string{},
[]PullRequest{},
NotDeletable,
})
}

for _, branch := range branches {
if branch.Name == defaultBranchName {
branch.Head = true
} else {
branch.Head = false
}
result = append(result, branch)
}

branches = result
}

sort.Slice(branches, func(i, j int) bool { return branches[i].Name < branches[j].Name })

return branches, nil
}

Expand Down Expand Up @@ -144,11 +194,11 @@ func trimBranch(oids []string, branchName string, conn Connection) ([]string, er
childNames := []string{}

for i, oid := range oids {
namesResult, err := conn.GetAssociatedBranchNames(oid)
refNames, err := conn.GetAssociatedRefNames(oid)
if err != nil {
return nil, err
}
names := splitLines(namesResult)
names := extractBranchNames(splitLines(refNames))

if i == 0 {
for _, name := range names {
Expand Down Expand Up @@ -179,6 +229,15 @@ func trimBranch(oids []string, branchName string, conn Connection) ([]string, er
return results, nil
}

func extractBranchNames(refNames []string) []string {
result := []string{}
r := regexp.MustCompile(`^refs/(?:heads|remotes/.+?)/`)
for _, name := range refNames {
result = append(result, r.ReplaceAllString(name, ""))
}
return result
}

func applyPullRequest(branches []Branch, prs []PullRequest) []Branch {
results := []Branch{}
for _, branch := range branches {
Expand Down Expand Up @@ -210,17 +269,17 @@ func findMatchedPullRequest(branchName string, prs []PullRequest) []PullRequest
return results
}

func checkDeletion(branches []Branch) []Branch {
func checkDeletion(branches []Branch, uncommittedChanges string) []Branch {
results := []Branch{}
for _, branch := range branches {
branch.State = getDeleteStatus(branch)
branch.State = getDeleteStatus(branch, uncommittedChanges)
results = append(results, branch)
}
return results
}

func getDeleteStatus(branch Branch) BranchState {
if branch.Head {
func getDeleteStatus(branch Branch, uncommittedChanges string) BranchState {
if branch.Head && len(uncommittedChanges) > 0 {
return NotDeletable
}

Expand Down Expand Up @@ -482,9 +541,9 @@ func (conn *ConnectionImpl) GetLog(branchName string) (string, error) {
return run("git", args)
}

func (conn *ConnectionImpl) GetAssociatedBranchNames(oid string) (string, error) {
func (conn *ConnectionImpl) GetAssociatedRefNames(oid string) (string, error) {
args := []string{
"branch", "--format=%(refname:lstrip=2)",
"branch", "--all", "--format=%(refname)",
"--contains", oid,
}
return run("git", args)
Expand Down Expand Up @@ -525,6 +584,18 @@ func (conn *ConnectionImpl) GetPullRequests(
return run("gh", args)
}

func (conn *ConnectionImpl) GetUncommittedChanges() (string, error) {
args := append([]string{
"status", "--short"})
return run("git", args)
}

func (conn *ConnectionImpl) CheckoutBranch(branchName string) (string, error) {
args := append([]string{
"checkout", "--quiet", branchName})
return run("git", args)
}

func (conn *ConnectionImpl) DeleteBranches(branchNames []string) (string, error) {
args := append([]string{
"branch", "-D"},
Expand Down
Loading

0 comments on commit 6b42a8a

Please sign in to comment.