From 27e43671415f3d7bfd8175c532117caa9f44cc69 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 14:45:46 +0200 Subject: [PATCH 01/19] Upgrade Python syntax with pyupgrade --- .github/workflows/lint.yml | 20 ++++++++++++++++++++ .github/workflows/lint_python.yml | 3 +-- .pre-commit-config.yaml | 9 +++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..8509763 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,20 @@ +name: Lint + +on: [push, pull_request, workflow_dispatch] + +env: + FORCE_COLOR: 1 + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 49d832c..18d39bb 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -12,7 +12,7 @@ jobs: - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - run: pip install --upgrade bandit black codespell flake8 flake8-bugbear - flake8-comprehensions isort mypy pyupgrade safety setuptools + flake8-comprehensions isort mypy safety setuptools - run: bandit --recursive --skip B101,B404,B603 . - run: black --diff . - run: codespell --ignore-words-list="commitish" @@ -21,5 +21,4 @@ jobs: - run: isort --check-only --profile black . - run: pip install --editable . - run: mypy --ignore-missing-imports --install-types --non-interactive . - - run: shopt -s globstar && pyupgrade --py38-plus **/*.py || true - run: safety check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..d58c0bb --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + - repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py38-plus] + +ci: + autoupdate_schedule: quarterly From ca95e6b6bfc3cea34bdae8f2bbc7d6065a7cad98 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 14:47:49 +0200 Subject: [PATCH 02/19] Format with Black --- .github/workflows/lint_python.yml | 3 +- .pre-commit-config.yaml | 5 +++ cherry_picker/cherry_picker.py | 13 ++++--- cherry_picker/test_cherry_picker.py | 58 ++++++++++++++++++++++------- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 18d39bb..3759400 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -11,10 +11,9 @@ jobs: cache-dependency-path: .github/workflows/lint_python.yml - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade bandit black codespell flake8 flake8-bugbear + - run: pip install --upgrade bandit codespell flake8 flake8-bugbear flake8-comprehensions isort mypy safety setuptools - run: bandit --recursive --skip B101,B404,B603 . - - run: black --diff . - run: codespell --ignore-words-list="commitish" - run: flake8 . --count --ignore=C408,E203,F841,W503 --max-complexity=10 --max-line-length=143 --show-source --statistics diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d58c0bb..4613f86 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,5 +5,10 @@ repos: - id: pyupgrade args: [--py38-plus] + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.9.1 + hooks: + - id: black + ci: autoupdate_schedule: quarterly diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index c3c6e60..77df8e6 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -91,7 +91,6 @@ class InvalidRepoException(Exception): class CherryPicker: - ALLOWED_STATES = WORKFLOW_STATES.BACKPORT_PAUSED, WORKFLOW_STATES.UNSET """The list of states expected at the start of the app.""" @@ -323,7 +322,9 @@ def get_updated_commit_message(self, cherry_pick_branch): commit_prefix = "" if self.prefix_commit: commit_prefix = f"[{get_base_branch(cherry_pick_branch)}] " - updated_commit_message = f"{commit_prefix}{self.get_commit_message(self.commit_sha1)}" + updated_commit_message = ( + f"{commit_prefix}{self.get_commit_message(self.commit_sha1)}" + ) # Add '(cherry picked from commit ...)' to the message # and add new Co-authored-by trailer if necessary. @@ -349,7 +350,9 @@ def get_updated_commit_message(self, cherry_pick_branch): # # This needs to be done because `git interpret-trailers` required us to add `:` # to `cherry_pick_information` when we don't actually want it. - before, after = output.strip().decode().rsplit(f"\n{cherry_pick_information}", 1) + before, after = ( + output.strip().decode().rsplit(f"\n{cherry_pick_information}", 1) + ) if not before.endswith("\n"): # ensure that we still have a newline between cherry pick information # and commit headline @@ -359,7 +362,7 @@ def get_updated_commit_message(self, cherry_pick_branch): return updated_commit_message def amend_commit_message(self, cherry_pick_branch): - """ prefix the commit message with (X.Y) """ + """prefix the commit message with (X.Y)""" updated_commit_message = self.get_updated_commit_message(cherry_pick_branch) if self.dry_run: @@ -442,7 +445,7 @@ def create_gh_pr(self, base_branch, head_branch, *, commit_message, gh_auth): if response.status_code == requests.codes.created: response_data = response.json() click.echo(f"Backport PR created at {response_data['html_url']}") - self.pr_number = response_data['number'] + self.pr_number = response_data["number"] else: click.echo(response.status_code) click.echo(response.text) diff --git a/cherry_picker/test_cherry_picker.py b/cherry_picker/test_cherry_picker.py index d99ea81..f36a506 100644 --- a/cherry_picker/test_cherry_picker.py +++ b/cherry_picker/test_cherry_picker.py @@ -131,7 +131,7 @@ def tmp_git_repo_dir(tmpdir, cd, git_init, git_commit, git_config): except subprocess.CalledProcessError: version = subprocess.run(("git", "--version"), capture_output=True) # the output looks like "git version 2.34.1" - v = version.stdout.decode("utf-8").removeprefix('git version ').split('.') + v = version.stdout.decode("utf-8").removeprefix("git version ").split(".") if (int(v[0]), int(v[1])) < (2, 28): warnings.warn( "You need git 2.28.0 or newer to run the full test suite.", @@ -264,7 +264,9 @@ def test_get_cherry_pick_branch(os_path_exists, config): ("python", "python"), ), ) -def test_upstream_name(remote_name, upstream_remote, config, tmp_git_repo_dir, git_remote): +def test_upstream_name( + remote_name, upstream_remote, config, tmp_git_repo_dir, git_remote +): git_remote("add", remote_name, "https://github.com/python/cpython.git") if remote_name != "origin": git_remote("add", "origin", "https://github.com/miss-islington/cpython.git") @@ -292,10 +294,14 @@ def test_upstream_name(remote_name, upstream_remote, config, tmp_git_repo_dir, g (None, "python", None), ), ) -def test_error_on_missing_remote(remote_to_add, remote_name, upstream_remote, config, tmp_git_repo_dir, git_remote): +def test_error_on_missing_remote( + remote_to_add, remote_name, upstream_remote, config, tmp_git_repo_dir, git_remote +): git_remote("add", "some-remote-name", "https://github.com/python/cpython.git") if remote_to_add is not None: - git_remote("add", remote_to_add, "https://github.com/miss-islington/cpython.git") + git_remote( + "add", remote_to_add, "https://github.com/miss-islington/cpython.git" + ) branches = ["3.6"] with mock.patch("cherry_picker.cherry_picker.validate_sha", return_value=True): @@ -610,7 +616,9 @@ def test_normalize_short_commit_message(): ), ), ) -def test_get_updated_commit_message_with_trailers(commit_message, expected_commit_message): +def test_get_updated_commit_message_with_trailers( + commit_message, expected_commit_message +): cherry_pick_branch = "backport-22a594a-3.6" commit = "b9ff498793611d1c6a9b99df464812931a1e2d69" @@ -625,7 +633,9 @@ def test_get_updated_commit_message_with_trailers(commit_message, expected_commi "cherry_picker.cherry_picker.get_author_info_from_short_sha", return_value="PR Author ", ): - updated_commit_message = cherry_picker.get_updated_commit_message(cherry_pick_branch) + updated_commit_message = cherry_picker.get_updated_commit_message( + cherry_pick_branch + ) assert updated_commit_message == expected_commit_message @@ -764,7 +774,9 @@ def test_cleanup_branch(tmp_git_repo_dir, git_checkout): assert get_current_branch() == "main" -def test_cleanup_branch_checkout_previous_branch(tmp_git_repo_dir, git_checkout, git_worktree): +def test_cleanup_branch_checkout_previous_branch( + tmp_git_repo_dir, git_checkout, git_worktree +): assert get_state() == WORKFLOW_STATES.UNSET with mock.patch("cherry_picker.cherry_picker.validate_sha", return_value=True): @@ -790,7 +802,9 @@ def test_cleanup_branch_fail(tmp_git_repo_dir): assert get_state() == WORKFLOW_STATES.REMOVING_BACKPORT_BRANCH_FAILED -def test_cleanup_branch_checkout_fail(tmp_git_repo_dir, tmpdir, git_checkout, git_worktree): +def test_cleanup_branch_checkout_fail( + tmp_git_repo_dir, tmpdir, git_checkout, git_worktree +): assert get_state() == WORKFLOW_STATES.UNSET with mock.patch("cherry_picker.cherry_picker.validate_sha", return_value=True): @@ -845,7 +859,7 @@ class tested_state: set_state(tested_state) expected_msg_regexp = ( - fr"^Run state cherry-picker.state={tested_state.name} in Git config " + rf"^Run state cherry-picker.state={tested_state.name} in Git config " r"is not known." "\n" r"Perhaps it has been set by a newer " @@ -1008,7 +1022,9 @@ def test_backport_cherry_pick_branch_already_exists( pr_remote, scm_revision, cherry_pick_target_branches ) - backport_branch_name = cherry_picker.get_cherry_pick_branch(cherry_pick_target_branches[0]) + backport_branch_name = cherry_picker.get_cherry_pick_branch( + cherry_pick_target_branches[0] + ) git_branch(backport_branch_name) with mock.patch.object(cherry_picker, "fetch_upstream"), pytest.raises( @@ -1055,7 +1071,15 @@ def test_backport_success( @pytest.mark.parametrize("already_committed", (True, False)) @pytest.mark.parametrize("push", (True, False)) def test_backport_pause_and_continue( - tmp_git_repo_dir, git_branch, git_add, git_commit, git_checkout, git_reset, git_remote, already_committed, push + tmp_git_repo_dir, + git_branch, + git_add, + git_commit, + git_checkout, + git_reset, + git_remote, + already_committed, + push, ): cherry_pick_target_branches = ("3.8",) pr_remote = "origin" @@ -1087,7 +1111,9 @@ def test_backport_pause_and_continue( if not already_committed: git_reset("HEAD~1") - assert len(get_commits_from_backport_branch(cherry_pick_target_branches[0])) == 0 + assert ( + len(get_commits_from_backport_branch(cherry_pick_target_branches[0])) == 0 + ) with mock.patch("cherry_picker.cherry_picker.validate_sha", return_value=True): cherry_picker = CherryPicker(pr_remote, "", [], push=push) @@ -1142,7 +1168,9 @@ def test_continue_cherry_pick_invalid_state(tmp_git_repo_dir): assert get_state() == WORKFLOW_STATES.UNSET - with pytest.raises(ValueError, match=re.compile(r"^One can only continue a paused process.")): + with pytest.raises( + ValueError, match=re.compile(r"^One can only continue a paused process.") + ): cherry_picker.continue_cherry_pick() assert get_state() == WORKFLOW_STATES.UNSET # success @@ -1168,7 +1196,9 @@ def test_abort_cherry_pick_invalid_state(tmp_git_repo_dir): assert get_state() == WORKFLOW_STATES.UNSET - with pytest.raises(ValueError, match=re.compile(r"^One can only abort a paused process.")): + with pytest.raises( + ValueError, match=re.compile(r"^One can only abort a paused process.") + ): cherry_picker.abort_cherry_pick() From 5a2a1f8988cafc65d3f8487053b095030e48124e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 14:50:24 +0200 Subject: [PATCH 03/19] Sort imports with isort --- .github/workflows/lint_python.yml | 3 +-- .pre-commit-config.yaml | 6 ++++++ cherry_picker/__init__.py | 2 ++ cherry_picker/__main__.py | 2 ++ cherry_picker/cherry_picker.py | 2 ++ cherry_picker/test_cherry_picker.py | 2 ++ pyproject.toml | 3 +++ 7 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 3759400..10a656d 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -12,12 +12,11 @@ jobs: - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - run: pip install --upgrade bandit codespell flake8 flake8-bugbear - flake8-comprehensions isort mypy safety setuptools + flake8-comprehensions mypy safety setuptools - run: bandit --recursive --skip B101,B404,B603 . - run: codespell --ignore-words-list="commitish" - run: flake8 . --count --ignore=C408,E203,F841,W503 --max-complexity=10 --max-line-length=143 --show-source --statistics - - run: isort --check-only --profile black . - run: pip install --editable . - run: mypy --ignore-missing-imports --install-types --non-interactive . - run: safety check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4613f86..9475e71 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,5 +10,11 @@ repos: hooks: - id: black + - repo: https://github.com/PyCQA/isort + rev: 5.12.0 + hooks: + - id: isort + args: [--add-import=from __future__ import annotations] + ci: autoupdate_schedule: quarterly diff --git a/cherry_picker/__init__.py b/cherry_picker/__init__.py index 5636972..195413d 100644 --- a/cherry_picker/__init__.py +++ b/cherry_picker/__init__.py @@ -1,2 +1,4 @@ """Backport CPython changes from main to maintenance branches.""" +from __future__ import annotations + __version__ = "2.2.0" diff --git a/cherry_picker/__main__.py b/cherry_picker/__main__.py index cc02b31..b5ff54f 100644 --- a/cherry_picker/__main__.py +++ b/cherry_picker/__main__.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from .cherry_picker import cherry_pick_cli if __name__ == "__main__": diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index 77df8e6..8ab3f7f 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from __future__ import annotations + import collections import enum import os diff --git a/cherry_picker/test_cherry_picker.py b/cherry_picker/test_cherry_picker.py index f36a506..8049a8e 100644 --- a/cherry_picker/test_cherry_picker.py +++ b/cherry_picker/test_cherry_picker.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os import pathlib import re diff --git a/pyproject.toml b/pyproject.toml index e47b7eb..ad365be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,3 +32,6 @@ dev = [ "pytest", "pytest-cov", ] + +[tool.isort] +profile = "black" From 704cb67636bd765ed733d9cb0d1275f7b525b395 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 14:58:58 +0200 Subject: [PATCH 04/19] Add and fix Flake8 warnings --- .flake8 | 4 ++++ .github/workflows/lint_python.yml | 6 ++---- .pre-commit-config.yaml | 13 ++++++++++++ cherry_picker/cherry_picker.py | 33 ++++++++++++++++++++--------- cherry_picker/test_cherry_picker.py | 11 ++++++---- 5 files changed, 49 insertions(+), 18 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..a991544 --- /dev/null +++ b/.flake8 @@ -0,0 +1,4 @@ +[flake8] +extend-ignore = C408,E203,F841,W503 +max-complexity=10 +max-line-length = 88 diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 10a656d..7d28553 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -11,12 +11,10 @@ jobs: cache-dependency-path: .github/workflows/lint_python.yml - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade bandit codespell flake8 flake8-bugbear - flake8-comprehensions mypy safety setuptools + - run: pip install --upgrade bandit codespell + mypy safety setuptools - run: bandit --recursive --skip B101,B404,B603 . - run: codespell --ignore-words-list="commitish" - - run: flake8 . --count --ignore=C408,E203,F841,W503 --max-complexity=10 - --max-line-length=143 --show-source --statistics - run: pip install --editable . - run: mypy --ignore-missing-imports --install-types --non-interactive . - run: safety check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9475e71..340234a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,5 +16,18 @@ repos: - id: isort args: [--add-import=from __future__ import annotations] + - repo: https://github.com/PyCQA/flake8 + rev: 6.1.0 + hooks: + - id: flake8 + additional_dependencies: + [ + flake8-2020, + flake8-bugbear, + flake8-comprehensions, + flake8-implicit-str-concat, + flake8-logging, + ] + ci: autoupdate_schedule: quarterly diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index 8ab3f7f..5422496 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -152,7 +152,9 @@ def set_paused_state(self): set_state(WORKFLOW_STATES.BACKPORT_PAUSED) def remember_previous_branch(self): - """Save the current branch into Git config to be able to get back to it later.""" + """Save the current branch into Git config + to be able to get back to it later. + """ current_branch = get_current_branch() save_cfg_vals_to_git_cfg(previous_branch=current_branch) @@ -161,7 +163,8 @@ def upstream(self): """Get the remote name to use for upstream branches Uses the remote passed to `--upstream-remote`. - If this flag wasn't passed, it uses "upstream" if it exists or "origin" otherwise. + If this flag wasn't passed, it uses "upstream" if it exists or "origin" + otherwise. """ # the cached calculated value of the property if self._upstream is not None: @@ -204,7 +207,10 @@ def get_cherry_pick_branch(self, maint_branch): return f"backport-{self.commit_sha1[:7]}-{maint_branch}" def get_pr_url(self, base_branch, head_branch): - return f"https://github.com/{self.config['team']}/{self.config['repo']}/compare/{base_branch}...{self.username}:{head_branch}?expand=1" + return ( + f"https://github.com/{self.config['team']}/{self.config['repo']}" + f"/compare/{base_branch}...{self.username}:{head_branch}?expand=1" + ) def fetch_upstream(self): """git fetch """ @@ -547,7 +553,9 @@ def abort_cherry_pick(self): state = self.get_state_and_verify() if state != WORKFLOW_STATES.BACKPORT_PAUSED: raise ValueError( - f"One can only abort a paused process. Current state: {state}. Expected state: {WORKFLOW_STATES.BACKPORT_PAUSED}" + "One can only abort a paused process. " + f"Current state: {state}. " + f"Expected state: {WORKFLOW_STATES.BACKPORT_PAUSED}" ) try: @@ -580,7 +588,9 @@ def continue_cherry_pick(self): state = self.get_state_and_verify() if state != WORKFLOW_STATES.BACKPORT_PAUSED: raise ValueError( - f"One can only continue a paused process. Current state: {state}. Expected state: {WORKFLOW_STATES.BACKPORT_PAUSED}" + "One can only continue a paused process. " + f"Current state: {state}. " + f"Expected state: {WORKFLOW_STATES.BACKPORT_PAUSED}" ) cherry_pick_branch = get_current_branch() @@ -628,7 +638,8 @@ def continue_cherry_pick(self): else: click.echo( - f"Current branch ({cherry_pick_branch}) is not a backport branch. Will not continue. \U0001F61B" + f"Current branch ({cherry_pick_branch}) is not a backport branch. " + "Will not continue. \U0001F61B" ) set_state(WORKFLOW_STATES.CONTINUATION_FAILED) @@ -640,8 +651,8 @@ def check_repo(self): """ 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. + 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: validate_sha(self.config["check_sha"]) @@ -828,7 +839,8 @@ def get_base_branch(cherry_pick_branch): if prefix != "backport": raise ValueError( - 'branch name is not prefixed with "backport-". Is this a cherry_picker branch?' + 'branch name is not prefixed with "backport-". ' + "Is this a cherry_picker branch?" ) if not re.match("[0-9a-f]{7,40}", sha): @@ -856,7 +868,8 @@ def validate_sha(sha): 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" + f"The sha listed in the branch name, {sha}, " + "is not present in the repository" ) diff --git a/cherry_picker/test_cherry_picker.py b/cherry_picker/test_cherry_picker.py index 8049a8e..bffb11d 100644 --- a/cherry_picker/test_cherry_picker.py +++ b/cherry_picker/test_cherry_picker.py @@ -389,7 +389,8 @@ def test_get_updated_commit_message_without_links_replacement(config): @mock.patch("subprocess.check_output") def test_is_cpython_repo(subprocess_check_output): - subprocess_check_output.return_value = """commit 7f777ed95a19224294949e1b4ce56bbffcb1fe9f + subprocess_check_output.return_value = """\ +commit 7f777ed95a19224294949e1b4ce56bbffcb1fe9f Author: Guido van Rossum Date: Thu Aug 9 14:25:15 1990 +0000 @@ -503,7 +504,8 @@ def test_load_config_no_head_sha(tmp_git_repo_dir, git_add, git_commit): def test_normalize_long_commit_message(): - commit_message = """[3.6] Fix broken `Show Source` links on documentation pages (GH-3113) + commit_message = """\ +[3.6] Fix broken `Show Source` links on documentation pages (GH-3113) The `Show Source` was broken because of a change made in sphinx 1.5.1 In Sphinx 1.4.9, the sourcename was "index.txt". @@ -529,7 +531,8 @@ def test_normalize_long_commit_message(): def test_normalize_short_commit_message(): - commit_message = """[3.6] Fix broken `Show Source` links on documentation pages (GH-3113) + commit_message = """\ +[3.6] Fix broken `Show Source` links on documentation pages (GH-3113) (cherry picked from commit b9ff498793611d1c6a9b99df464812931a1e2d69) @@ -879,7 +882,7 @@ class tested_state: with mock.patch( "cherry_picker.cherry_picker.validate_sha", return_value=True ), pytest.raises(InvalidRepoException, match=expected_msg_regexp): - cherry_picker = CherryPicker("origin", "xxx", []) + CherryPicker("origin", "xxx", []) def test_push_to_remote_fail(tmp_git_repo_dir): From da786e7595cccec3690127a60420b94e2418d1dd Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:00:39 +0200 Subject: [PATCH 05/19] Add more pre-commit checks --- .pre-commit-config.yaml | 17 +++++++++++++++++ readme.rst | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 340234a..a050535 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,5 +29,22 @@ repos: flake8-logging, ] + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: python-check-blanket-noqa + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-case-conflict + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-json + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: trailing-whitespace ci: autoupdate_schedule: quarterly diff --git a/readme.rst b/readme.rst index 7724ce5..612a226 100644 --- a/readme.rst +++ b/readme.rst @@ -18,7 +18,7 @@ of the maintenance branches (``3.6``, ``3.5``, ``2.7``). workflow as CPython. See the configuration file options below for more details. The maintenance branch names should contain some sort of version number (X.Y). -For example: ``3.6``, ``3.5``, ``2.7``, ``stable-2.6``, ``2.5-lts``, are all +For example: ``3.6``, ``3.5``, ``2.7``, ``stable-2.6``, ``2.5-lts``, are all supported branch names. It will prefix the commit message with the branch, e.g. ``[3.6]``, and then From 31cdcbd27f4cfcfc90a3a775ab181dd983fa2530 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:06:57 +0200 Subject: [PATCH 06/19] Format pyproject.toml for easy comparison with other projects --- .pre-commit-config.yaml | 11 +++++++++ pyproject.toml | 51 +++++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a050535..9f21d4d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,5 +46,16 @@ repos: - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace + + - repo: https://github.com/tox-dev/pyproject-fmt + rev: 1.2.0 + hooks: + - id: pyproject-fmt + + - repo: https://github.com/abravalheri/validate-pyproject + rev: v0.14 + hooks: + - id: validate-pyproject + ci: autoupdate_schedule: quarterly diff --git a/pyproject.toml b/pyproject.toml index ad365be..cc896ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,37 +1,44 @@ [build-system] -requires = ["flit_core>=3.2,<4"] build-backend = "flit_core.buildapi" +requires = [ + "flit_core<4,>=3.2", +] [project] -name = "cherry_picker" -authors = [{ name = "Mariatta Wijaya", email = "mariatta@python.org" }] +name = "cherry-picker" +readme = "readme.rst" maintainers = [{ name = "Python Core Developers", email = "core-workflow@python.org" }] +authors = [{ name = "Mariatta Wijaya", email = "mariatta@python.org" }] +requires-python = ">=3.8" +classifiers = [ + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +dynamic = [ + "description", + "version", +] dependencies = [ - "click>=6.0", - "gidgethub", - "requests", - "tomli>=1.1.0;python_version<'3.11'", + "click>=6", + "gidgethub", + "requests", + 'tomli>=1.1; python_version < "3.11"', ] -readme = "readme.rst" -classifiers = [ - "Programming Language :: Python :: 3.8", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", +[project.optional-dependencies] +dev = [ + "pytest", + "pytest-cov", ] -requires-python = ">=3.8" -dynamic = ["version", "description"] - [project.urls] "Homepage" = "https://github.com/python/cherry-picker" - [project.scripts] cherry_picker = "cherry_picker.cherry_picker:cherry_pick_cli" -[project.optional-dependencies] -dev = [ - "pytest", - "pytest-cov", -] - [tool.isort] profile = "black" From b9a7b247e9dc6984499ac28a0a12851f3a47fff5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:26:29 +0200 Subject: [PATCH 07/19] Add bandit to pre-commit --- .github/workflows/lint_python.yml | 3 +-- .pre-commit-config.yaml | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 7d28553..8601c62 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -11,9 +11,8 @@ jobs: cache-dependency-path: .github/workflows/lint_python.yml - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade bandit codespell + - run: pip install --upgrade codespell mypy safety setuptools - - run: bandit --recursive --skip B101,B404,B603 . - run: codespell --ignore-words-list="commitish" - run: pip install --editable . - run: mypy --ignore-missing-imports --install-types --non-interactive . diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f21d4d..40e2f5d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,6 +16,12 @@ repos: - id: isort args: [--add-import=from __future__ import annotations] + - repo: https://github.com/PyCQA/bandit + rev: 1.7.5 + hooks: + - id: bandit + args: ["--skip=B101,B404,B603"] + - repo: https://github.com/PyCQA/flake8 rev: 6.1.0 hooks: From 735bb52c94547b97f9a8a705d1bc062b502e370b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:28:38 +0200 Subject: [PATCH 08/19] Add codespell to pre-commit --- .github/workflows/lint_python.yml | 4 +--- .pre-commit-config.yaml | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 8601c62..57f57dc 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -11,9 +11,7 @@ jobs: cache-dependency-path: .github/workflows/lint_python.yml - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade codespell - mypy safety setuptools - - run: codespell --ignore-words-list="commitish" + - run: pip install --upgrade mypy safety setuptools - run: pip install --editable . - run: mypy --ignore-missing-imports --install-types --non-interactive . - run: safety check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 40e2f5d..151ff56 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -63,5 +63,11 @@ repos: hooks: - id: validate-pyproject + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 + hooks: + - id: codespell + args: [--ignore-words-list=commitish] + ci: autoupdate_schedule: quarterly From 4abea3d82cf523c034c77758381898ed973a727b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:40:20 +0200 Subject: [PATCH 09/19] Add mypy to pre-commit --- .github/workflows/lint_python.yml | 4 +--- .pre-commit-config.yaml | 23 +++++++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 57f57dc..820d892 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -11,7 +11,5 @@ jobs: cache-dependency-path: .github/workflows/lint_python.yml - run: pip install --upgrade pip wheel # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade mypy safety setuptools - - run: pip install --editable . - - run: mypy --ignore-missing-imports --install-types --non-interactive . + - run: pip install --upgrade safety setuptools - run: safety check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 151ff56..a00f4e7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,8 +19,8 @@ repos: - repo: https://github.com/PyCQA/bandit rev: 1.7.5 hooks: - - id: bandit - args: ["--skip=B101,B404,B603"] + - id: bandit + args: ["--skip=B101,B404,B603"] - repo: https://github.com/PyCQA/flake8 rev: 6.1.0 @@ -53,6 +53,21 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.6.0 + hooks: + - id: mypy + args: + [ + --ignore-missing-imports, + --install-types, + --non-interactive, + --pretty, + --show-error-codes, + ., + ] + pass_filenames: false + - repo: https://github.com/tox-dev/pyproject-fmt rev: 1.2.0 hooks: @@ -66,8 +81,8 @@ repos: - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: - - id: codespell - args: [--ignore-words-list=commitish] + - id: codespell + args: [--ignore-words-list=commitish] ci: autoupdate_schedule: quarterly From 48825bb77e5dd4fc25408425835a5c5213930165 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Wed, 11 Oct 2023 15:43:00 +0200 Subject: [PATCH 10/19] Move safety to lint.yml --- .github/workflows/lint.yml | 9 +++++++++ .github/workflows/lint_python.yml | 15 --------------- 2 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 .github/workflows/lint_python.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 8509763..078b253 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -17,4 +17,13 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.x" + cache: pip + cache-dependency-path: .github/workflows/lint_python.yml - uses: pre-commit/action@v3.0.0 + - name: Install dependencies + run: | + python -m pip install --upgrade pip wheel + # TODO: remove setuptools installation when safety==2.4.0 is released + python -m pip install --upgrade safety setuptools + python -m pip install --editable . + - run: safety check diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml deleted file mode 100644 index 820d892..0000000 --- a/.github/workflows/lint_python.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: lint_python -on: [pull_request, push, workflow_dispatch] -jobs: - lint_python: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 - with: - cache: pip - cache-dependency-path: .github/workflows/lint_python.yml - - run: pip install --upgrade pip wheel - # TODO: remove setuptools installation when safety==2.4.0 is released - - run: pip install --upgrade safety setuptools - - run: safety check From a9ddb874792285c18a3a69fa4fe851792b4c80b5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Tue, 17 Oct 2023 11:06:41 -0600 Subject: [PATCH 11/19] Add whitespace Co-authored-by: Ezio Melotti --- .flake8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index a991544..3ed1b92 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,4 @@ [flake8] extend-ignore = C408,E203,F841,W503 -max-complexity=10 +max-complexity = 10 max-line-length = 88 From a0eef4acc231a57d37c2a9f5dd1c2d40eb1cab3c Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Fri, 20 Oct 2023 07:32:10 +0300 Subject: [PATCH 12/19] Add f to string segment without placeholders Co-authored-by: Ezio Melotti --- cherry_picker/cherry_picker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index 5422496..50a5c09 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -553,7 +553,7 @@ def abort_cherry_pick(self): state = self.get_state_and_verify() if state != WORKFLOW_STATES.BACKPORT_PAUSED: raise ValueError( - "One can only abort a paused process. " + f"One can only abort a paused process. " f"Current state: {state}. " f"Expected state: {WORKFLOW_STATES.BACKPORT_PAUSED}" ) From 70505effe0ae28b9afd7621794d5b64a4c3c2ef4 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 12 Nov 2023 19:10:42 +0200 Subject: [PATCH 13/19] Update pre-commit --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a00f4e7..60b577c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: args: [--py38-plus] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.9.1 + rev: 23.11.0 hooks: - id: black @@ -54,7 +54,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.0 + rev: v1.7.0 hooks: - id: mypy args: @@ -69,12 +69,12 @@ repos: pass_filenames: false - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.2.0 + rev: 1.5.1 hooks: - id: pyproject-fmt - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.14 + rev: v0.15 hooks: - id: validate-pyproject From fb20a18b17a18e731d81eae2f52bb41102553583 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 31 Dec 2023 17:04:11 +0200 Subject: [PATCH 14/19] Update cache-dependency-path and bump GitHub Actions --- .github/workflows/lint.yml | 4 ++-- .github/workflows/main.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 078b253..0721496 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,11 +14,11 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.x" cache: pip - cache-dependency-path: .github/workflows/lint_python.yml + cache-dependency-path: .github/workflows/lint.yml - uses: pre-commit/action@v3.0.0 - name: Install dependencies run: | diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2eaf4f9..77b25fe 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,13 +14,13 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] os: [windows-latest, macos-latest, ubuntu-latest] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # fetch all branches and tags # ref actions/checkout#448 fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true From b17da2f3689c2a250239f517762e9c13f390f16f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Sun, 31 Dec 2023 17:05:44 +0200 Subject: [PATCH 15/19] Update pre-commit --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 60b577c..4016114 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,18 +6,18 @@ repos: args: [--py38-plus] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.11.0 + rev: 23.12.1 hooks: - id: black - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort args: [--add-import=from __future__ import annotations] - repo: https://github.com/PyCQA/bandit - rev: 1.7.5 + rev: 1.7.6 hooks: - id: bandit args: ["--skip=B101,B404,B603"] @@ -54,7 +54,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.7.0 + rev: v1.8.0 hooks: - id: mypy args: @@ -69,7 +69,7 @@ repos: pass_filenames: false - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.5.1 + rev: 1.5.3 hooks: - id: pyproject-fmt From 2d3a122d54dfca638976b8dcda3ff6fe8957490e Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 20 Jan 2024 07:46:20 -0700 Subject: [PATCH 16/19] Capitalise docstring Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- cherry_picker/cherry_picker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index 50a5c09..c3aa93c 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -370,7 +370,7 @@ def get_updated_commit_message(self, cherry_pick_branch): return updated_commit_message def amend_commit_message(self, cherry_pick_branch): - """prefix the commit message with (X.Y)""" + """Prefix the commit message with (X.Y)""" updated_commit_message = self.get_updated_commit_message(cherry_pick_branch) if self.dry_run: From da3163363d61314be5418211ff9283dc236dd151 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:47:21 +0200 Subject: [PATCH 17/19] Bump pre-commit --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4016114..c5fbb02 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: args: ["--skip=B101,B404,B603"] - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 additional_dependencies: @@ -69,7 +69,7 @@ repos: pass_filenames: false - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.5.3 + rev: 1.6.0 hooks: - id: pyproject-fmt From a2e08904270bd71ec158b690e62b6720623e7a6d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 20 Jan 2024 09:29:48 -0700 Subject: [PATCH 18/19] Shorten docstring Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> --- cherry_picker/cherry_picker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index c3aa93c..8f34bd9 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -152,8 +152,7 @@ def set_paused_state(self): set_state(WORKFLOW_STATES.BACKPORT_PAUSED) def remember_previous_branch(self): - """Save the current branch into Git config - to be able to get back to it later. + """Save the current branch into Git config, to be used later.""" """ current_branch = get_current_branch() save_cfg_vals_to_git_cfg(previous_branch=current_branch) From bd636adae7933c539d2451d910435539d0475fd5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 20 Jan 2024 09:31:21 -0700 Subject: [PATCH 19/19] Oops --- cherry_picker/cherry_picker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cherry_picker/cherry_picker.py b/cherry_picker/cherry_picker.py index 8f34bd9..66bde15 100755 --- a/cherry_picker/cherry_picker.py +++ b/cherry_picker/cherry_picker.py @@ -153,7 +153,6 @@ def set_paused_state(self): def remember_previous_branch(self): """Save the current branch into Git config, to be used later.""" - """ current_branch = get_current_branch() save_cfg_vals_to_git_cfg(previous_branch=current_branch)