From 113eb2131931013ee1ec3b3a282f109ce7b37f69 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Sat, 16 Jun 2018 16:03:19 -0700 Subject: [PATCH 1/2] Validate a branch that we parse when running cherry_picker --continue 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. Relies on the changes here: https://github.com/python/core-workflow/pull/265 (which does the work of one of the validations) --- cherry_picker/cherry_picker/cherry_picker.py | 34 ++++++++++++++++---- cherry_picker/cherry_picker/test.py | 27 +++++++++++++--- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/cherry_picker/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker/cherry_picker.py index bf0d516..eb2fdf2 100755 --- a/cherry_picker/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker/cherry_picker.py @@ -74,12 +74,7 @@ def upstream(self): @property def sorted_branches(self): - def version_from_branch(branch): - try: - return tuple(map(int, re.match(r'^.*(?P\d+(\.\d+)+).*$', branch).groupdict()['version'].split('.'))) - except AttributeError as attr_err: - raise ValueError(f'Branch {branch} seems to not have a version in its name.') from attr_err - + """Return the branches to cherry-pick to, sorted by version""" return sorted( self.branches, reverse=True, @@ -423,9 +418,36 @@ def get_base_branch(cherry_pick_branch): return '2.7' from 'backport-sha-2.7' """ prefix, sha, base_branch = cherry_pick_branch.split('-', 2) + + if prefix != 'backport': + raise ValueError('branch name is not prefixed with "backport-". Is this a cherry_picker branch?') + + if not re.match('[0-9a-f]{7,40}', sha): + raise ValueError(f'branch name has an invalid sha: {sha}') + + cmd = ['git', 'log', '-r', sha] + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.SubprocessError: + raise ValueError(f'The sha listed in the branch name, {sha}, is not present in the repository') + + # Subject the parsed base_branch to the same tests as when we generated it + # This throws a ValueError if the base_branch doesn't need our requirements + version_from_branch(base_branch) + return base_branch +def version_from_branch(branch): + """ + return version information from a git branch name + """ + try: + return tuple(map(int, re.match(r'^.*(?P\d+(\.\d+)+).*$', branch).groupdict()['version'].split('.'))) + except AttributeError as attr_err: + raise ValueError(f'Branch {branch} seems to not have a version in its name.') from attr_err + + def get_current_branch(): """ Return the current branch diff --git a/cherry_picker/cherry_picker/test.py b/cherry_picker/cherry_picker/test.py index 2fcfd57..52e46ab 100644 --- a/cherry_picker/cherry_picker/test.py +++ b/cherry_picker/cherry_picker/test.py @@ -32,19 +32,36 @@ def changedir(d): os.chdir(cwd) -def test_get_base_branch(): - # The format of cherry-pick branches we create are "backport-{SHA}-{base_branch}" - cherry_pick_branch = 'backport-afc23f4-2.7' +@mock.patch('subprocess.check_output') +def test_get_base_branch(subprocess_check_output): + # The format of cherry-pick branches we create are:: + # backport-{SHA}-{base_branch} + subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c' + cherry_pick_branch = 'backport-22a594a-2.7' result = get_base_branch(cherry_pick_branch) assert result == '2.7' -def test_get_base_branch_which_has_dashes(): - cherry_pick_branch ='backport-afc23f4-baseprefix-2.7-basesuffix' +@mock.patch('subprocess.check_output') +def test_get_base_branch_which_has_dashes(subprocess_check_output): + subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c' + cherry_pick_branch = 'backport-22a594a-baseprefix-2.7-basesuffix' result = get_base_branch(cherry_pick_branch) assert result == 'baseprefix-2.7-basesuffix' +@pytest.mark.parametrize('cherry_pick_branch', ['backport-22a594a', # Not enough fields + 'prefix-22a594a-2.7', # Not the prefix we were expecting + 'backport-22a594a-base', # No version info in the base branch + ] + ) +@mock.patch('subprocess.check_output') +def test_get_base_branch_invalid(subprocess_check_output, cherry_pick_branch): + subprocess_check_output.return_value = b'22a594a0047d7706537ff2ac676cdc0f1dcb329c' + with pytest.raises(ValueError): + get_base_branch(cherry_pick_branch) + + @mock.patch('subprocess.check_output') def test_get_current_branch(subprocess_check_output): subprocess_check_output.return_value = b'master' From 4eba21fa55b5215e5b88906a939a3d56e41a5e2f Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Fri, 22 Jun 2018 08:24:31 -0700 Subject: [PATCH 2/2] Extract the validation of a sha within the repo to a common function --- cherry_picker/cherry_picker/cherry_picker.py | 41 ++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/cherry_picker/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker/cherry_picker.py index eb2fdf2..1a689c4 100755 --- a/cherry_picker/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker/cherry_picker.py @@ -74,7 +74,7 @@ def upstream(self): @property def sorted_branches(self): - """Return the branches to cherry-pick to, sorted by version""" + """Return the branches to cherry-pick to, sorted by version.""" return sorted( self.branches, reverse=True, @@ -349,12 +349,15 @@ def continue_cherry_pick(self): click.echo(f"Current branch ({cherry_pick_branch}) is not a backport branch. Will not continue. \U0001F61B") def check_repo(self): - # CPython repo has a commit with - # SHA=7f777ed95a19224294949e1b4ce56bbffcb1fe9f - cmd = ['git', 'log', '-r', self.config['check_sha']] + """ + Check that the repository is for the project we're configured to operate on. + + This function performs the check by making sure that the sha specified in the config + is present in the repository that we're operating on. + """ try: - subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.SubprocessError: + validate_sha(self.config['check_sha']) + except ValueError: raise InvalidRepoException() @@ -416,6 +419,9 @@ def cherry_pick_cli(dry_run, pr_remote, abort, status, push, config_path, def get_base_branch(cherry_pick_branch): """ return '2.7' from 'backport-sha-2.7' + + raises ValueError if the specified branch name is not of a form that + cherry_picker would have created """ prefix, sha, base_branch = cherry_pick_branch.split('-', 2) @@ -425,19 +431,30 @@ def get_base_branch(cherry_pick_branch): if not re.match('[0-9a-f]{7,40}', sha): raise ValueError(f'branch name has an invalid sha: {sha}') - cmd = ['git', 'log', '-r', sha] - try: - subprocess.check_output(cmd, stderr=subprocess.STDOUT) - except subprocess.SubprocessError: - raise ValueError(f'The sha listed in the branch name, {sha}, is not present in the repository') + # Validate that the sha refers to a valid commit within the repo + # Throws a ValueError if the sha is not present in the repo + validate_sha(sha) # Subject the parsed base_branch to the same tests as when we generated it - # This throws a ValueError if the base_branch doesn't need our requirements + # This throws a ValueError if the base_branch doesn't meet our requirements version_from_branch(base_branch) return base_branch +def validate_sha(sha): + """ + Validate that a hexdigest sha is a valid commit in the repo + + raises ValueError if the sha does not reference a commit within the repo + """ + cmd = ['git', 'log', '-r', sha] + try: + subprocess.check_output(cmd, stderr=subprocess.STDOUT) + except subprocess.SubprocessError: + raise ValueError(f'The sha listed in the branch name, {sha}, is not present in the repository') + + def version_from_branch(branch): """ return version information from a git branch name pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy