Skip to content
Draft
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
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."
)

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"
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:
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"]
self._exec_install_pre_commit_hook(hook_types)
out.write("commitizen pre-commit hook is now installed in your '.git'\n")
18 changes: 9 additions & 9 deletions commitizen/cz/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Any, Callable, Protocol

from jinja2 import BaseLoader, PackageLoader
from prompt_toolkit.styles import Style, merge_styles
from prompt_toolkit.styles import Style

from commitizen import git
from commitizen.config.base_config import BaseConfig
Expand Down Expand Up @@ -77,25 +77,25 @@ def message(self, answers: Mapping[str, Any]) -> str:

@property
def style(self) -> Style:
return merge_styles(
return Style(
[
Style(BaseCommitizen.default_style_config),
Style(self.config.settings["style"]),
*BaseCommitizen.default_style_config,
*self.config.settings["style"],
]
) # type: ignore[return-value]
)

@abstractmethod
def example(self) -> str:
"""Example of the commit message."""
raise NotImplementedError("Not Implemented yet")

@abstractmethod
def schema(self) -> str:
"""Schema definition of the commit message."""
raise NotImplementedError("Not Implemented yet")

@abstractmethod
def schema_pattern(self) -> str:
"""Regex matching the schema used for message validation."""
raise NotImplementedError("Not Implemented yet")

@abstractmethod
def info(self) -> str:
"""Information about the standardized commit message."""
raise NotImplementedError("Not Implemented yet")
1 change: 1 addition & 0 deletions commitizen/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class Settings(TypedDict, total=False):
"Pull request",
"fixup!",
"squash!",
"amend!",
],
"changelog_file": "CHANGELOG.md",
"changelog_format": None, # default guessed from changelog_file
Expand Down
2 changes: 1 addition & 1 deletion commitizen/providers/uv_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class UvProvider(TomlProvider):
"""
uv.lock and pyproject.tom version management
uv.lock and pyproject.toml version management
"""

filename = "pyproject.toml"
Expand Down
2 changes: 1 addition & 1 deletion tests/commands/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


@pytest.fixture()
def config():
def mock_config():
Copy link
Member

Choose a reason for hiding this comment

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

We're not mocking a config here. We're providing a sample config instead. mock_config is inaccurate. I probably would try sample_config or something similiar

_config = BaseConfig()
_config.settings.update({"name": defaults.DEFAULT_SETTINGS["name"]})
return _config
Expand Down
2 changes: 1 addition & 1 deletion tests/commands/test_bump_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ def test_bump_dry_run(mocker: MockFixture, capsys):
assert tag_exists is False


def test_bump_in_non_git_project(tmpdir, config, mocker: MockFixture):
def test_bump_in_non_git_project(tmpdir, mock_config, mocker: MockFixture):
testargs = ["cz", "bump", "--yes"]
mocker.patch.object(sys, "argv", testargs)

Expand Down
23 changes: 12 additions & 11 deletions tests/commands/test_changelog_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,17 +279,18 @@ def test_changelog_incremental_keep_a_changelog_sample(

@pytest.mark.usefixtures("tmp_commitizen_project")
@pytest.mark.parametrize("dry_run", [True, False])
def test_changelog_hook(mocker: MockFixture, config: BaseConfig, dry_run: bool):
def test_changelog_hook(mocker: MockFixture, mock_config: BaseConfig, dry_run: bool):
changelog_hook_mock = mocker.Mock()
changelog_hook_mock.return_value = "cool changelog hook"

create_file_and_commit("feat: new file")
create_file_and_commit("refactor: is in changelog")
create_file_and_commit("Merge into master")

config.settings["change_type_order"] = ["Refactor", "Feat"] # type: ignore[typeddict-unknown-key]
mock_config.settings["change_type_order"] = ["Refactor", "Feat"] # type: ignore[typeddict-unknown-key]
changelog = Changelog(
config, {"unreleased_version": None, "incremental": True, "dry_run": dry_run}
mock_config,
{"unreleased_version": None, "incremental": True, "dry_run": dry_run},
)
mocker.patch.object(changelog.cz, "changelog_hook", changelog_hook_mock)
try:
Expand Down Expand Up @@ -330,7 +331,7 @@ def test_changelog_hook_customize(mocker: MockFixture, config_customize):


@pytest.mark.usefixtures("tmp_commitizen_project")
def test_changelog_release_hook(mocker: MockFixture, config):
def test_changelog_release_hook(mocker: MockFixture, mock_config):
def changelog_release_hook(release: dict, tag: git.GitTag) -> dict:
return release

Expand All @@ -340,9 +341,9 @@ def changelog_release_hook(release: dict, tag: git.GitTag) -> dict:
create_file_and_commit("Merge into master")
git.tag(f"0.{i + 1}.0")

# changelog = Changelog(config, {})
# changelog = Changelog(mock_config, {})
changelog = Changelog(
config, {"unreleased_version": None, "incremental": True, "dry_run": False}
mock_config, {"unreleased_version": None, "incremental": True, "dry_run": False}
)
mocker.patch.object(changelog.cz, "changelog_release_hook", changelog_release_hook)
spy = mocker.spy(changelog.cz, "changelog_release_hook")
Expand Down Expand Up @@ -529,7 +530,7 @@ def test_changelog_with_different_tag_name_and_changelog_content(
cli.main()


def test_changelog_in_non_git_project(tmpdir, config, mocker: MockFixture):
def test_changelog_in_non_git_project(tmpdir, mock_config, mocker: MockFixture):
testargs = ["cz", "changelog", "--incremental"]
mocker.patch.object(sys, "argv", testargs)

Expand Down Expand Up @@ -1382,7 +1383,7 @@ def test_changelog_prerelease_rev_with_use_scheme_semver(


@pytest.mark.usefixtures("tmp_commitizen_project")
def test_changelog_uses_version_tags_for_header(mocker: MockFixture, config):
def test_changelog_uses_version_tags_for_header(mocker: MockFixture, mock_config):
"""Tests that changelog headers always use version tags even if there are non-version tags

This tests a scenario fixed in this commit:
Expand All @@ -1396,7 +1397,7 @@ def test_changelog_uses_version_tags_for_header(mocker: MockFixture, config):
write_patch = mocker.patch("commitizen.commands.changelog.out.write")

changelog = Changelog(
config, {"dry_run": True, "incremental": True, "unreleased_version": None}
mock_config, {"dry_run": True, "incremental": True, "unreleased_version": None}
)

with pytest.raises(DryRunExit):
Expand All @@ -1411,7 +1412,7 @@ def test_changelog_uses_version_tags_for_header(mocker: MockFixture, config):

@pytest.mark.usefixtures("tmp_commitizen_project")
def test_changelog_from_current_version_tag_with_nonversion_tag(
mocker: MockFixture, config
mocker: MockFixture, mock_config
):
"""Tests that changelog generation for a single version works even if
there is a non-version tag in the list of tags
Expand Down Expand Up @@ -1450,7 +1451,7 @@ def test_changelog_from_current_version_tag_with_nonversion_tag(
write_patch = mocker.patch("commitizen.commands.changelog.out.write")

changelog = Changelog(
config,
mock_config,
{
"dry_run": True,
"incremental": False,
Expand Down
Loading
Loading