Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c341234

Browse filesBrowse files
abadgerMariatta
authored andcommitted
Validate a branch that we parse when running cherry_picker --continue (#266)
When running cherry_picker --continue we count on being able to get certain information from the branch's name which cherry_picker constructed earlier. Verify as best we can that the branch name is one which cherry_picker could have constructed.
1 parent ff8a587 commit c341234
Copy full SHA for c341234

File tree

2 files changed

+72
-16
lines changed
Filter options

2 files changed

+72
-16
lines changed

‎cherry_picker/cherry_picker/cherry_picker.py

Copy file name to clipboardExpand all lines: cherry_picker/cherry_picker/cherry_picker.py
+50-11Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,7 @@ def upstream(self):
7474

7575
@property
7676
def sorted_branches(self):
77-
def version_from_branch(branch):
78-
try:
79-
return tuple(map(int, re.match(r'^.*(?P<version>\d+(\.\d+)+).*$', branch).groupdict()['version'].split('.')))
80-
except AttributeError as attr_err:
81-
raise ValueError(f'Branch {branch} seems to not have a version in its name.') from attr_err
82-
77+
"""Return the branches to cherry-pick to, sorted by version."""
8378
return sorted(
8479
self.branches,
8580
reverse=True,
@@ -354,12 +349,15 @@ def continue_cherry_pick(self):
354349
click.echo(f"Current branch ({cherry_pick_branch}) is not a backport branch. Will not continue. \U0001F61B")
355350

356351
def check_repo(self):
357-
# CPython repo has a commit with
358-
# SHA=7f777ed95a19224294949e1b4ce56bbffcb1fe9f
359-
cmd = ['git', 'log', '-r', self.config['check_sha']]
352+
"""
353+
Check that the repository is for the project we're configured to operate on.
354+
355+
This function performs the check by making sure that the sha specified in the config
356+
is present in the repository that we're operating on.
357+
"""
360358
try:
361-
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
362-
except subprocess.SubprocessError:
359+
validate_sha(self.config['check_sha'])
360+
except ValueError:
363361
raise InvalidRepoException()
364362

365363

@@ -421,11 +419,52 @@ def cherry_pick_cli(dry_run, pr_remote, abort, status, push, config_path,
421419
def get_base_branch(cherry_pick_branch):
422420
"""
423421
return '2.7' from 'backport-sha-2.7'
422+
423+
raises ValueError if the specified branch name is not of a form that
424+
cherry_picker would have created
424425
"""
425426
prefix, sha, base_branch = cherry_pick_branch.split('-', 2)
427+
428+
if prefix != 'backport':
429+
raise ValueError('branch name is not prefixed with "backport-". Is this a cherry_picker branch?')
430+
431+
if not re.match('[0-9a-f]{7,40}', sha):
432+
raise ValueError(f'branch name has an invalid sha: {sha}')
433+
434+
# Validate that the sha refers to a valid commit within the repo
435+
# Throws a ValueError if the sha is not present in the repo
436+
validate_sha(sha)
437+
438+
# Subject the parsed base_branch to the same tests as when we generated it
439+
# This throws a ValueError if the base_branch doesn't meet our requirements
440+
version_from_branch(base_branch)
441+
426442
return base_branch
427443

428444

445+
def validate_sha(sha):
446+
"""
447+
Validate that a hexdigest sha is a valid commit in the repo
448+
449+
raises ValueError if the sha does not reference a commit within the repo
450+
"""
451+
cmd = ['git', 'log', '-r', sha]
452+
try:
453+
subprocess.check_output(cmd, stderr=subprocess.STDOUT)
454+
except subprocess.SubprocessError:
455+
raise ValueError(f'The sha listed in the branch name, {sha}, is not present in the repository')
456+
457+
458+
def version_from_branch(branch):
459+
"""
460+
return version information from a git branch name
461+
"""
462+
try:
463+
return tuple(map(int, re.match(r'^.*(?P<version>\d+(\.\d+)+).*$', branch).groupdict()['version'].split('.')))
464+
except AttributeError as attr_err:
465+
raise ValueError(f'Branch {branch} seems to not have a version in its name.') from attr_err
466+
467+
429468
def get_current_branch():
430469
"""
431470
Return the current branch

‎cherry_picker/cherry_picker/test.py

Copy file name to clipboardExpand all lines: cherry_picker/cherry_picker/test.py
+22-5Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,36 @@ def changedir(d):
3232
os.chdir(cwd)
3333

3434

35-
def test_get_base_branch():
36-
# The format of cherry-pick branches we create are "backport-{SHA}-{base_branch}"
37-
cherry_pick_branch = 'backport-afc23f4-2.7'
35+
@mock.patch('subprocess.check_output')
36+
def test_get_base_branch(subprocess_check_output):
37+
# The format of cherry-pick branches we create are::
38+
# backport-{SHA}-{base_branch}
39+
subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c'
40+
cherry_pick_branch = 'backport-22a594a-2.7'
3841
result = get_base_branch(cherry_pick_branch)
3942
assert result == '2.7'
4043

4144

42-
def test_get_base_branch_which_has_dashes():
43-
cherry_pick_branch ='backport-afc23f4-baseprefix-2.7-basesuffix'
45+
@mock.patch('subprocess.check_output')
46+
def test_get_base_branch_which_has_dashes(subprocess_check_output):
47+
subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c'
48+
cherry_pick_branch = 'backport-22a594a-baseprefix-2.7-basesuffix'
4449
result = get_base_branch(cherry_pick_branch)
4550
assert result == 'baseprefix-2.7-basesuffix'
4651

4752

53+
@pytest.mark.parametrize('cherry_pick_branch', ['backport-22a594a', # Not enough fields
54+
'prefix-22a594a-2.7', # Not the prefix we were expecting
55+
'backport-22a594a-base', # No version info in the base branch
56+
]
57+
)
58+
@mock.patch('subprocess.check_output')
59+
def test_get_base_branch_invalid(subprocess_check_output, cherry_pick_branch):
60+
subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c'
61+
with pytest.raises(ValueError):
62+
get_base_branch(cherry_pick_branch)
63+
64+
4865
@mock.patch('subprocess.check_output')
4966
def test_get_current_branch(subprocess_check_output):
5067
subprocess_check_output.return_value = b'master'

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.