Skip to content

Commit

Permalink
[git-webkit] Make target PR remote sticky
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=248085
rdar://102515722

Reviewed by Darin Adler.

* Tools/Scripts/libraries/webkitscmpy/setup.py: Bump version.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/pull_request.py:
(PullRequest.create_pull_request): Prompt user if we're making a pull-request against a different different remote
than the specified local branch last made a pull request against.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/pull_request_unittest.py:

Canonical link: https://commits.webkit.org/257072@main
  • Loading branch information
JonWBedard committed Nov 28, 2022
1 parent 1b6e607 commit c52dcd0
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Tools/Scripts/libraries/webkitscmpy/setup.py
Expand Up @@ -29,7 +29,7 @@ def readme():

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

version = Version(5, 7, 11)
version = Version(5, 8, 0)

AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('jinja2', Version(2, 11, 3)))
Expand Down
Expand Up @@ -353,32 +353,68 @@ def create_pull_request(cls, repository, args, branch_point, callback=None, unbl
issue = issues[0] if issues else None

remote_repo = repository.remote(name=source_remote)
if isinstance(remote_repo, remote.GitHub) and issue and issue.redacted and args.remote is None:
print('{} is considered the primary issue for your pull request'.format(issue.link))
print("{} {}".format(issue.link, issue.redacted))
print("Pull request needs to be sent to a secure remote for review")
original_remote = source_remote
if len(repository.source_remotes()) < 2:
sys.stderr.write("Error. You do not have access to a secure remote to make a pull request for a redacted issue\n")
if args.defaults or Terminal.choose(
"Would you like to proceed anyways? \n",
default='No',
) == 'No':
sys.stderr.write("Failed to create pull request due to unsuitable remote\n")
return 1
else:
source_remote = repository.source_remotes()[1]
if args.defaults or Terminal.choose(
"Would you like to make a pull request against '{}' instead of '{}'? \n".format(source_remote, original_remote),
default='Yes',
) == 'No':
sys.stderr.write("User declined to create a pull request against the secure remote '{}'\n".format(source_remote))
return 1
remote_repo = repository.remote(name=source_remote)
print("Making PR against '{}' instead of '{}'".format(source_remote, original_remote))

if not remote_repo:
sys.stderr.write("'{}' doesn't have a recognized remote\n".format(repository.root_path))
return 1

previous_target = repository.config().get('branch.{}.target'.format(repository.branch))
if previous_target and previous_target != source_remote:
if args.remote:
sys.stderr.write("'{}' was previously made against the '{}' remote\n".format(repository.branch, previous_target))
sys.stderr.write("User over-rode and is now making that PR against '{}'\n".format(specified_target_remote))
elif args.defaults:
sys.stderr.write("'{}' was previously made against the '{}' remote\n".format(repository.branch, previous_target))
sys.stderr.write("Prevailing issue indicates it should be made against '{}'\n".format(source_remote))
sys.stderr.write("Cannot automatically determine which is correct, canceling pull-request\n")
return 1
else:
response = Terminal.choose(
"'{}' was previously made against the '{}' remote, but the prevailing issue indicates it should be made against '{}'\n"
"Which remote would you like to make your pull request against?".format(repository.branch, previous_target, source_remote),
options=('Cancel', 'Use {} (previous)'.format(previous_target), 'Use {} (new)'.format(source_remote)),
default='Cancel', numbered=True
)
match = re.match(r'Use (.+) \((previous|new)\)', response)
if not match:
sys.stderr.write("User canceled pull-request because new remote target '{}' did not match previous remote target '{}'\n".format(
source_remote, previous_target,
))
return 1
source_remote = match.group(1)
print("Making the PR against the '{}' remote".format(source_remote))

if run(
[repository.executable(), 'config', 'branch.{}.target'.format(repository.branch), source_remote],
cwd=repository.root_path, capture_output=True,
).returncode:
sys.stderr.write("Failed to set the target of '{}' to '{}'\n".format(repository.branch, source_remote))

if isinstance(remote_repo, remote.GitHub):
if issue and issue.redacted and args.remote is None:
print('{} is considered the primary issue for your pull request'.format(issue.link))
print("{} {}".format(issue.link, issue.redacted))
print("Pull request needs to be sent to a secure remote for review")
original_remote = source_remote
if len(repository.source_remotes()) < 2:
sys.stderr.write("Error. You do not have access to a secure remote to make a pull request for a redacted issue\n")
if args.defaults or Terminal.choose(
"Would you like to proceed anyways? \n",
default='No',
) == 'No':
sys.stderr.write("Failed to create pull request due to unsuitable remote\n")
return 1
else:
source_remote = repository.source_remotes()[1]
if args.defaults or Terminal.choose(
"Would you like to make a pull request against '{}' instead of '{}'? \n".format(source_remote, original_remote),
default='Yes',
) == 'No':
sys.stderr.write("User declined to create a pull request against the secure remote '{}'\n".format(source_remote))
return 1
remote_repo = repository.remote(name=source_remote)
print("Making PR against '{}' instead of '{}'".format(source_remote, original_remote))
target = 'fork' if source_remote == repository.default_remote else '{}-fork'.format(source_remote)

if not repository.config().get('remote.{}.url'.format(target)):
sys.stderr.write("'{}' is not a remote in this repository. Have you run `{} setup` yet?\n".format(
source_remote, os.path.basename(sys.argv[0]),
Expand All @@ -387,10 +423,6 @@ def create_pull_request(cls, repository, args, branch_point, callback=None, unbl
else:
target = source_remote

if not remote_repo:
sys.stderr.write("'{}' doesn't have a recognized remote\n".format(repository.root_path))
return 1

existing_pr = None
if remote_repo.pull_requests:
user, _ = remote_repo.credentials(required=False)
Expand Down
Expand Up @@ -467,6 +467,102 @@ def test_github_update(self):
],
)

def test_github_sticky_remote(self):
with mocks.remote.GitHub(remote='github.example.com/WebKit/WebKit-security') as remote, mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
remotes={
'fork': 'https://{}/Contributor/WebKit'.format(remote.hosts[0]),
'security': 'https://{}/WebKit/WebKit-security'.format(remote.hosts[0]),
'security-fork': 'https://{}/Contributor/WebKit-security'.format(remote.hosts[0]),
},
) as repo, mocks.local.Svn(), patch('webkitbugspy.Tracker._trackers', []):
with OutputCapture():
repo.staged['added.txt'] = 'added'
self.assertEqual(0, program.main(
args=('pull-request', '-i', 'pr-branch', '--remote', 'security'),
path=self.path,
))

with OutputCapture(level=logging.INFO) as captured:
repo.staged['added.txt'] = 'diff'
self.assertEqual(1, program.main(
args=('pull-request', '-v', '--no-history', '--defaults'),
path=self.path,
))

self.assertEqual(captured.stdout.getvalue(), '')
self.assertEqual(
captured.stderr.getvalue(),
"'eng/pr-branch' was previously made against the 'security' remote\n"
"Prevailing issue indicates it should be made against 'origin'\n"
"Cannot automatically determine which is correct, canceling pull-request\n",
)
log = captured.root.log.getvalue().splitlines()
self.assertEqual(
[line for line in log if 'Mock process' not in line], [
' Found 1 commit...',
"Amending commit...",
"Rebasing 'eng/pr-branch' on 'main'...",
"Rebased 'eng/pr-branch' on 'main!'",
'Running pre-PR checks...',
'No pre-PR checks to run',
],
)

def test_github_sticky_remote_prompt(self):
with mocks.remote.GitHub(remote='github.example.com/WebKit/WebKit-security') as remote, mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
remotes={
'fork': 'https://{}/Contributor/WebKit'.format(remote.hosts[0]),
'security': 'https://{}/WebKit/WebKit-security'.format(remote.hosts[0]),
'security-fork': 'https://{}/Contributor/WebKit-security'.format(remote.hosts[0]),
},
) as repo, mocks.local.Svn(), patch('webkitbugspy.Tracker._trackers', []):
with OutputCapture():
repo.staged['added.txt'] = 'added'
self.assertEqual(0, program.main(
args=('pull-request', '-i', 'pr-branch', '--remote', 'security'),
path=self.path,
))

with OutputCapture(level=logging.INFO) as captured, MockTerminal.input('2'):
repo.staged['added.txt'] = 'diff'
self.assertEqual(0, program.main(
args=('pull-request', '-v', '--no-history'),
path=self.path,
))

self.assertEqual(
captured.stdout.getvalue(),
"'eng/pr-branch' was previously made against the 'security' remote, but the prevailing issue indicates it should be made against 'origin'\n"
"Which remote would you like to make your pull request against?:\n"
" 1) [Cancel]\n"
" 2) Use security (previous)\n"
" 3) Use origin (new)\n"
": \n"
"Making the PR against the 'security' remote\n"
"Updated 'PR 1 | [Testing] Amending commits'!\n"
"https://github.example.com/WebKit/WebKit-security/pull/1\n",
)
self.assertEqual(captured.stderr.getvalue(), '')
log = captured.root.log.getvalue().splitlines()
self.assertEqual(
[line for line in log if 'Mock process' not in line], [
' Found 1 commit...',
"Amending commit...",
"Rebasing 'eng/pr-branch' on 'main'...",
"Rebased 'eng/pr-branch' on 'main!'",
'Running pre-PR checks...',
'No pre-PR checks to run',
'Checking if PR already exists...',
'PR #1 found.',
'Checking PR labels for active labels...',
"Pushing 'eng/pr-branch' to 'security-fork'...",
"Syncing 'main' to remote 'security-fork'",
"Updating pull-request for 'eng/pr-branch'...",
],
)

def test_github_append(self):
with mocks.remote.GitHub() as remote, mocks.local.Git(
self.path, remote='https://{}'.format(remote.remote),
Expand Down

0 comments on commit c52dcd0

Please sign in to comment.