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

Sign up
Appearance settings

fix(Init): raise InitFailedError on keyboard interrupt on pre-commit ... #1604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Lee-W merged 1 commit into commitizen-tools:v4-9-2 from bearomorphism:fix-hook-types
Sep 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 34 additions & 48 deletions commitizen/commands/init.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,43 @@ def __call__(self) -> None:
tag_format = self._ask_tag_format(tag) # confirm & text
update_changelog_on_bump = self._ask_update_changelog_on_bump() # confirm
major_version_zero = self._ask_major_version_zero(version) # confirm
hook_types: list[str] | None = questionary.checkbox(
"What types of pre-commit hook you want to install? (Leave blank if you don't want to install)",
choices=[
questionary.Choice("commit-msg", checked=False),
questionary.Choice("pre-push", checked=False),
],
).unsafe_ask()
except KeyboardInterrupt:
raise InitFailedError("Stopped by user")

if hook_types:
config_data = self._get_config_data()
with smart_open(
self._PRE_COMMIT_CONFIG_PATH, "w", encoding=self.encoding
) as config_file:
yaml.safe_dump(config_data, stream=config_file)

if not self.project_info.is_pre_commit_installed:
raise InitFailedError(
"Failed to install pre-commit hook.\n"
"pre-commit is not installed in current environment."
Copy link
Contributor Author

@bearomorphism bearomorphism Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is also added to keep the original behavior.

)

cmd_str = "pre-commit install " + " ".join(
f"--hook-type {ty}" for ty in hook_types
)
c = cmd.run(cmd_str)
if c.return_code != 0:
raise InitFailedError(
"Failed to install pre-commit hook.\n"
Copy link
Contributor Author

@bearomorphism bearomorphism Sep 15, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just added this line to keep the original behavior.

f"Error running {cmd_str}."
"Outputs are attached below:\n"
f"stdout: {c.out}\n"
f"stderr: {c.err}"
)
out.write("commitizen pre-commit hook is now installed in your '.git'\n")

# Initialize configuration
if "toml" in config_path:
self.config = TomlConfig(data="", path=config_path)
Expand All @@ -161,20 +195,6 @@ def __call__(self) -> None:
elif "yaml" in config_path:
self.config = YAMLConfig(data="", path=config_path)

# Collect hook data
hook_types = questionary.checkbox(
"What types of pre-commit hook you want to install? (Leave blank if you don't want to install)",
choices=[
questionary.Choice("commit-msg", checked=False),
questionary.Choice("pre-push", checked=False),
],
).unsafe_ask()
if hook_types:
try:
self._install_pre_commit_hook(hook_types)
except InitFailedError as e:
raise InitFailedError(f"Failed to install pre-commit hook.\n{e}")

# Create and initialize config
self.config.init_empty_config_content()

Expand Down Expand Up @@ -321,26 +341,6 @@ def _ask_update_changelog_on_bump(self) -> bool:
).unsafe_ask()
return update_changelog_on_bump

def _exec_install_pre_commit_hook(self, hook_types: list[str]) -> None:
cmd_str = self._gen_pre_commit_cmd(hook_types)
c = cmd.run(cmd_str)
if c.return_code != 0:
err_msg = (
f"Error running {cmd_str}."
"Outputs are attached below:\n"
f"stdout: {c.out}\n"
f"stderr: {c.err}"
)
raise InitFailedError(err_msg)

def _gen_pre_commit_cmd(self, hook_types: list[str]) -> str:
"""Generate pre-commit command according to given hook types"""
if not hook_types:
Copy link
Contributor Author

@bearomorphism bearomorphism Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This not hook_types is again redundant.

raise ValueError("At least 1 hook type should be provided.")
return "pre-commit install " + " ".join(
f"--hook-type {ty}" for ty in hook_types
)

def _get_config_data(self) -> dict[str, Any]:
CZ_HOOK_CONFIG = {
"repo": "https://github.com/commitizen-tools/commitizen",
Expand Down Expand Up @@ -369,17 +369,3 @@ def _get_config_data(self) -> dict[str, Any]:
else:
repos.append(CZ_HOOK_CONFIG)
return config_data

def _install_pre_commit_hook(self, hook_types: list[str] | None = None) -> None:
config_data = self._get_config_data()
with smart_open(
self._PRE_COMMIT_CONFIG_PATH, "w", encoding=self.encoding
) as config_file:
yaml.safe_dump(config_data, stream=config_file)

if not self.project_info.is_pre_commit_installed:
raise InitFailedError("pre-commit is not installed in current environment.")
if hook_types is None:
hook_types = ["commit-msg", "pre-push"]
Comment on lines -382 to -383
Copy link
Contributor Author

@bearomorphism bearomorphism Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch is redundant. hook_types is never None as we already checked it at callsite.

self._exec_install_pre_commit_hook(hook_types)
out.write("commitizen pre-commit hook is now installed in your '.git'\n")
29 changes: 3 additions & 26 deletions tests/commands/test_init_command.py
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import yaml
from pytest_mock import MockFixture

from commitizen import cli, commands
from commitizen import cli, cmd, commands
from commitizen.__version__ import __version__
from commitizen.config.base_config import BaseConfig
from commitizen.exceptions import InitFailedError, NoAnswersError
Expand Down Expand Up @@ -117,12 +117,6 @@ def test_init_without_choosing_tag(config: BaseConfig, mocker: MockFixture, tmpd
commands.Init(config)()


def test_executed_pre_commit_command(config: BaseConfig):
init = commands.Init(config)
expected_cmd = "pre-commit install --hook-type commit-msg --hook-type pre-push"
assert init._gen_pre_commit_cmd(["commit-msg", "pre-push"]) == expected_cmd


@pytest.fixture(scope="function")
def pre_commit_installed(mocker: MockFixture):
# Assume the `pre-commit` is installed
Expand All @@ -132,8 +126,8 @@ def pre_commit_installed(mocker: MockFixture):
)
# And installation success (i.e. no exception raised)
mocker.patch(
"commitizen.commands.init.Init._exec_install_pre_commit_hook",
return_value=None,
"commitizen.cmd.run",
return_value=cmd.Command("0.0.1", "", b"", b"", 0),
)


Expand Down Expand Up @@ -244,23 +238,6 @@ def test_pre_commit_not_installed(
with pytest.raises(InitFailedError):
commands.Init(config)()

def test_pre_commit_exec_failed(
_, mocker: MockFixture, config: BaseConfig, default_choice: str, tmpdir
):
# Assume `pre-commit` is installed
mocker.patch(
"commitizen.commands.init.ProjectInfo.is_pre_commit_installed",
return_value=True,
)
# But pre-commit installation will fail
mocker.patch(
"commitizen.commands.init.Init._exec_install_pre_commit_hook",
side_effect=InitFailedError("Mock init failed error."),
)
with tmpdir.as_cwd():
with pytest.raises(InitFailedError):
commands.Init(config)()


class TestAskTagFormat:
def test_confirm_v_tag_format(self, mocker: MockFixture, config: BaseConfig):
Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /