Skip to content
Permalink
Browse files
[git-webkit] clean all dead pr branches
https://bugs.webkit.org/show_bug.cgi?id=240589
<rdar://93521924>

Reviewed by Aakash Jain.

* Tools/Scripts/libraries/webkitscmpy/setup.py: Bump version.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py:
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/clean.py:
(DeletePRBranches): Iterate through all local branches and remove those
associated with a closed PR.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/clean_unittest.py:
(TestClean.test_delete_pr_branches):

Canonical link: https://commits.webkit.org/250953@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294797 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
JonWBedard committed May 25, 2022
1 parent 60a5bb3 commit d6ff115c44c141b69ab5216680e5ffef5d39ebe5
Showing 5 changed files with 75 additions and 7 deletions.
@@ -29,7 +29,7 @@ def readme():

setup(
name='webkitscmpy',
version='4.14.5',
version='4.15.0',
description='Library designed to interact with git and svn repositories.',
long_description=readme(),
classifiers=[
@@ -46,7 +46,7 @@ def _maybe_add_webkitcorepy_path():
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)

version = Version(4, 14, 5)
version = Version(4, 15, 0)

AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('jinja2', Version(2, 11, 3)))
@@ -28,7 +28,7 @@
from .blame import Blame
from .branch import Branch
from .canonicalize import Canonicalize
from .clean import Clean
from .clean import Clean, DeletePRBranches
from .command import Command
from .commit import Commit
from .checkout import Checkout
@@ -79,7 +79,7 @@ def main(
Blame, Branch, Canonicalize, Checkout,
Clean, Find, Info, Land, Log, Pull,
PullRequest, Revert, Setup, InstallGitLFS,
Credentials, Commit,
Credentials, Commit, DeletePRBranches,
]
if subversion:
programs.append(SetupGitSvn)
@@ -24,15 +24,16 @@
import sys

from .command import Command
from webkitcorepy import arguments, run, Terminal
from webkitscmpy import local, remote
from webkitcorepy import run, Terminal
from webkitscmpy import log, remote


class Clean(Command):
name = 'clean'
help = 'Remove all local changes from current checkout or delete local and remote branches associated with a pull-request'

PR_RE = re.compile(r'^\[?[Pp][Rr][ -](?P<number>\d+)]?$')
REMOTE_RE = re.compile(r'^remote\.(?P<name>\S+)\.fetch$')

@classmethod
def parser(cls, parser, loggers=None):
@@ -49,7 +50,7 @@ def parser(cls, parser, loggers=None):
@classmethod
def cleanup(cls, repository, argument, remote_target=None):
if not repository.is_git:
sys.stderr('Can only cleanup branches on git repositories\n')
sys.stderr.write('Can only clean up branches on git repositories\n')
return 1

rmt = repository.remote(name=remote_target)
@@ -114,3 +115,51 @@ def main(cls, args, repository, **kwargs):
for argument in args.arguments:
result += cls.cleanup(repository, argument, remote_target=args.remote)
return result


class DeletePRBranches(Command):
name = 'delete-pr-branches'
help = 'Iterate through all local development branches, find matching PRs and, if those PRs are closed, delete the local branches.'

@classmethod
def parser(cls, parser, loggers=None):
parser.add_argument(
'--remote', dest='remote', type=str, default=None,
help='Specify remote to search for pull request from.',
)

@classmethod
def main(cls, args, repository, **kwargs):
if not repository:
sys.stderr.write('No repository provided\n')
return 1
if not repository.path:
sys.stderr.write('Cannot clean on remote repository "{}"\n'.format(repository.url))
return 1

rmt = repository.remote(name=args.remote)
if not rmt.pull_requests:
sys.stderr.write("'{}' does not have associated pull-requests\n".format(rmt.url))
return 1

result = 0
for branch in repository.branches_for(remote=False):
if not repository.dev_branches.match(branch):
continue
log.info('Checking {}...'.format(branch))
prs = list(rmt.pull_requests.find(opened=None, head=branch))
if not prs:
continue
if any([pr.opened for pr in prs]):
continue
result += Clean.cleanup(repository, branch, remote_target=args.remote)

for name in repository.config().keys():
match = Clean.REMOTE_RE.match(name)
if not match:
continue
name = match.group('name')
log.info('Deleting {}...'.format(name))
result += run([repository.executable(), 'fetch', name, '-f'], cwd=repository.root_path).returncode

return result
@@ -87,3 +87,22 @@ def test_clean_pr(self):
path=self.path,
))
self.assertNotIn('eng/pr-branch', repo.commits)

def test_delete_pr_branches(self):
with OutputCapture(), mocks.remote.GitHub() as remote, mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
remotes=dict(fork='https://{}/Contributor/WebKit'.format(remote.hosts[0])),
) as repo, mocks.local.Svn():
repo.staged['added.txt'] = 'added'
self.assertEqual(0, program.main(
args=('pull-request', '-i', 'pr-branch'),
path=self.path,
))
remote.pull_requests[-1]['state'] = 'closed'

self.assertIn('eng/pr-branch', repo.commits)
self.assertEqual(0, program.main(
args=('delete-pr-branches', '-v'),
path=self.path,
))
self.assertNotIn('eng/pr-branch', repo.commits)

0 comments on commit d6ff115

Please sign in to comment.