From 12b56ad6375bb116e6554b8771b27c7adbbc237f Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 4 May 2022 16:40:05 +0100 Subject: [PATCH 1/4] feat(bump): let it respect pre-commit reformats when bumping Fix https://github.com/commitizen-tools/commitizen/issues/502. Just add `--retry` to `cz bump` and it will attempt to commit twice if the 1st commit fails. Useful if your 1st commit runs a formatter that can for example change the contents of CHANGELOG.md. --- commitizen/cli.py | 6 +++ commitizen/commands/bump.py | 14 ++++++- tests/test_bump_create_commit_message.py | 50 +++++++++++++++++++++++- 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/commitizen/cli.py b/commitizen/cli.py index d9f1025ba2..90abc55453 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -165,6 +165,12 @@ "default": False, "help": "Output changelog to the stdout", }, + { + "name": ["--retry"], + "action": "store_true", + "default": False, + "help": "retry commit if it fails the 1st time", + }, ], }, { diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index cd05e8a8f3..e0779cd625 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -1,3 +1,4 @@ +from logging import getLogger from typing import List, Optional import questionary @@ -18,6 +19,8 @@ NoVersionSpecifiedError, ) +logger = getLogger("commitizen") + class Bump: """Show prompt for the user to create a guided commit.""" @@ -49,6 +52,7 @@ def __init__(self, config: BaseConfig, arguments: dict): self.changelog_to_stdout = arguments["changelog_to_stdout"] self.no_verify = arguments["no_verify"] self.check_consistency = arguments["check_consistency"] + self.retry = arguments["retry"] def is_initial_tag(self, current_tag_version: str, is_yes: bool = False) -> bool: """Check if reading the whole git tree up to HEAD is needed.""" @@ -209,7 +213,7 @@ def __call__(self): # noqa: C901 }, ) changelog_cmd() - c = cmd.run(f"git add {changelog_cmd.file_name}") + c = cmd.run(f"git add {changelog_cmd.file_name} {' '.join(version_files)}") self.config.set_key("version", str(new_version)) @@ -217,8 +221,14 @@ def __call__(self): # noqa: C901 raise ExpectedExit() c = git.commit(message, args=self._get_commit_args()) + if self.retry and c.return_code != 0 and self.changelog: + # Maybe pre-commit reformatted some files? Retry once + logger.debug("1st git.commit error: %s", c.err) + logger.info("1st commit attempt failed; retrying once") + cmd.run(f"git add {changelog_cmd.file_name} {' '.join(version_files)}") + c = git.commit(message, args=self._get_commit_args()) if c.return_code != 0: - raise BumpCommitFailedError(f'git.commit error: "{c.err.strip()}"') + raise BumpCommitFailedError(f'2nd git.commit error: "{c.err.strip()}"') c = git.tag( new_tag_version, annotated=self.bump_settings.get("annotated_tag", False) diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 4923d0a66c..937905dd96 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -1,7 +1,11 @@ +import sys +from pathlib import Path +from textwrap import dedent + import pytest from packaging.version import Version -from commitizen import bump +from commitizen import bump, cli, cmd conversion = [ ( @@ -20,3 +24,47 @@ def test_create_tag(test_input, expected): Version(current_version), Version(new_version), message_template ) assert new_tag == expected + + +@pytest.mark.parametrize("retry", (True, False)) +def test_bump_pre_commit_changelog(tmp_commitizen_project, mocker, freezer, retry): + freezer.move_to("2022-04-01") + testargs = ["cz", "bump", "--changelog", "--yes"] + if retry: + testargs.append("--retry") + else: + pytest.xfail("it will fail because pre-commit will reformat CHANGELOG.md") + mocker.patch.object(sys, "argv", testargs) + with tmp_commitizen_project.as_cwd(): + # Configure prettier as a pre-commit hook + Path(".pre-commit-config.yaml").write_text( + """ + repos: + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v2.6.2 + hooks: + - id: prettier + stages: [commit] + """ + ) + # Prettier inherits editorconfig + Path(".editorconfig").write_text( + """ + [*] + indent_size = 4 + """ + ) + cmd.run("git add -A") + cmd.run("git commit -m 'fix: _test'") + cmd.run("pre-commit install") + cli.main() + # Pre-commit fixed last line adding extra indent and "\" char + assert Path("CHANGELOG.md").read_text() == dedent( + """\ + ## 0.1.1 (2022-04-01) + + ### Fix + + - \\_test + """ + ) From ed2154155a6ff3dda680d274d4ea6bad53e583f7 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 10 May 2022 17:04:21 +0100 Subject: [PATCH 2/4] docs: document --retry Includes an update to the `cz bump --help` output. --- docs/bump.md | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/docs/bump.md b/docs/bump.md index cbf7fef171..8062044a76 100644 --- a/docs/bump.md +++ b/docs/bump.md @@ -54,32 +54,38 @@ Some examples: ```bash $ cz bump --help -usage: cz bump [-h] [--dry-run] [--files-only] [--changelog] [--no-verify] [--local-version] - [--yes] [--tag-format TAG_FORMAT] [--bump-message BUMP_MESSAGE] - [--prerelease {alpha,beta,rc}] - [--increment {MAJOR,MINOR,PATCH}] [--check-consistency] [--annotated-tag] +usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog] + [--no-verify] [--yes] [--tag-format TAG_FORMAT] + [--bump-message BUMP_MESSAGE] [--prerelease {alpha,beta,rc}] + [--increment {MAJOR,MINOR,PATCH}] [--check-consistency] + [--annotated-tag] [--changelog-to-stdout] [--retry] -optional arguments: +options: -h, --help show this help message and exit --dry-run show output to stdout, no commit, no modified files --files-only bump version in the files from the config + --local-version bump only the local version portion --changelog, -ch generate the changelog for the newest version - --no-verify this option bypasses the pre-commit and commit-msg hooks + --no-verify this option bypasses the pre-commit and commit-msg + hooks --yes accept automatically questions done - --local-version bump the local portion of the version --tag-format TAG_FORMAT - the format used to tag the commit and read it, use it in existing projects, wrap - around simple quotes + the format used to tag the commit and read it, use it + in existing projects, wrap around simple quotes --bump-message BUMP_MESSAGE - template used to create the release commit, useful when working with CI + template used to create the release commit, useful + when working with CI --prerelease {alpha,beta,rc}, -pr {alpha,beta,rc} choose type of prerelease --increment {MAJOR,MINOR,PATCH} manually specify the desired increment --check-consistency, -cc - check consistency among versions defined in commitizen configuration and - version_files + check consistency among versions defined in commitizen + configuration and version_files --annotated-tag, -at create annotated tag instead of lightweight one + --changelog-to-stdout + Output changelog to the stdout + --retry retry commit if it fails the 1st time ``` ### `--files-only` @@ -179,6 +185,13 @@ Example: cz bump --changelog --changelog-to-stdout > body.md ``` +### `--retry` + +If you use tools like [pre-commit](https://pre-commit.com/), add this flag. +It will retry the commit if it fails the 1st time. + +Useful to combine with code formatters, like [Prettier](https://prettier.io/). + ## Avoid raising errors Some situations from commitizen rise an exit code different than 0. From 44f5b3e1fcab8ac9b8b64936e3a11f9f5da14546 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 13 May 2022 11:53:02 +0100 Subject: [PATCH 3/4] test: assert that a failing commit condition will fail always, both with or without --retry --- tests/test_bump_create_commit_message.py | 31 +++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 937905dd96..ee1f1f768c 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -5,7 +5,7 @@ import pytest from packaging.version import Version -from commitizen import bump, cli, cmd +from commitizen import bump, cli, cmd, exceptions conversion = [ ( @@ -68,3 +68,32 @@ def test_bump_pre_commit_changelog(tmp_commitizen_project, mocker, freezer, retr - \\_test """ ) + + +@pytest.mark.parametrize("retry", (True, False)) +def test_bump_pre_commit_changelog_fails_always( + tmp_commitizen_project, mocker, freezer, retry +): + freezer.move_to("2022-04-01") + testargs = ["cz", "bump", "--changelog", "--yes"] + if retry: + testargs.append("--retry") + mocker.patch.object(sys, "argv", testargs) + with tmp_commitizen_project.as_cwd(): + Path(".pre-commit-config.yaml").write_text( + """ + repos: + - repo: local + hooks: + - id: forbid-changelog + name: changelogs are forbidden + entry: changelogs are forbidden + language: fail + files: CHANGELOG.md + """ + ) + cmd.run("git add -A") + cmd.run("git commit -m 'feat: forbid changelogs'") + cmd.run("pre-commit install") + with pytest.raises(exceptions.BumpCommitFailedError): + cli.main() From 79165119817cbd0aef25434a85dcbffa3a13acbb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 May 2022 13:56:52 +0000 Subject: [PATCH 4/4] =?UTF-8?q?bump:=20version=202.26.0=20=E2=86=92=202.27?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 6 ++++++ commitizen/__version__.py | 2 +- pyproject.toml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0b35236af7..bda2544ed6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: no-commit-to-branch - repo: https://github.com/commitizen-tools/commitizen - rev: v2.26.0 # automatically updated by Commitizen + rev: v2.27.0 # automatically updated by Commitizen hooks: - id: commitizen stages: [commit-msg] diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ab570e94b..a4c4b09f36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,10 @@ +## v2.27.0 (2022-05-16) + +### Feat + +- **bump**: let it respect pre-commit reformats when bumping + ## v2.26.0 (2022-05-14) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 23077358e7..07150ef8e0 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "2.26.0" +__version__ = "2.27.0" diff --git a/pyproject.toml b/pyproject.toml index eaef38369b..f9766220e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "2.26.0" +version = "2.27.0" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -30,7 +30,7 @@ exclude = ''' [tool.poetry] name = "commitizen" -version = "2.26.0" +version = "2.27.0" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT"