Skip to content
Open
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
16 changes: 11 additions & 5 deletions commitizen/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,24 +171,30 @@ def _ask_config_path(self) -> Path:
def _ask_name(self) -> str:
name: str = questionary.select(
f"Please choose a cz (commit rule): (default: {DEFAULT_SETTINGS['name']})",
choices=self._construct_name_choice_with_description(),
default=DEFAULT_SETTINGS["name"],
choices=self._construct_name_choices_from_registry(),
style=self.cz.style,
).unsafe_ask()
return name

def _construct_name_choice_with_description(self) -> list[questionary.Choice]:
def _construct_name_choices_from_registry(self) -> list[questionary.Choice]:
"""
Construct questionary choices of cz names from registry.
"""
choices = []
for cz_name, cz_class in registry.items():
try:
cz_obj = cz_class(self.config)
except MissingCzCustomizeConfigError:
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, I'm not sure whether this is compatible with plugins. Should we use general exception?

wdyt @Lee-W

Copy link
Member

Choose a reason for hiding this comment

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

why do you think it might not be compatible

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I thought other plugins throw other exceptions when they initialize with empty config, but we actually always initialize that with a BaseConfig object.

# Fallback if description is not available
choices.append(questionary.Choice(title=cz_name, value=cz_name))
continue
first_example = cz_obj.schema().partition("\n")[0]

# Get the first line of the schema as the description
Copy link
Member

Choose a reason for hiding this comment

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

we'd better add a description in v5. schema looks like a workaround for me

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it does not have to be a v5 feature. We can make description optional.

# TODO(bearomorphism): schema is a workaround. Add a description method to the cz class.
description = cz_obj.schema().partition("\n")[0]
choices.append(
questionary.Choice(
title=cz_name, value=cz_name, description=first_example
title=cz_name, value=cz_name, description=description
)
)
return choices
Expand Down
29 changes: 13 additions & 16 deletions tests/commands/test_init_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from commitizen import cmd, commands
from commitizen.__version__ import __version__
from commitizen.cz import registry
from commitizen.exceptions import InitFailedError, NoAnswersError

if TYPE_CHECKING:
Expand Down Expand Up @@ -466,20 +465,18 @@ def test_init_configuration_with_version_provider(
) # Version should not be set when using version_provider


def test_construct_name_choice_with_description(
config: BaseConfig, mocker: MockFixture
):
def test_construct_name_choice_from_registry(config: BaseConfig):
"""Test the construction of cz name choices with descriptions."""
init = commands.Init(config)
# mock the registry to have only one cz for testing
mocker.patch.dict(
"commitizen.cz.registry",
{"cz_conventional_commits": registry["cz_conventional_commits"]},
clear=True,
choices = commands.Init(config)._construct_name_choices_from_registry()
assert choices[0].title == "cz_conventional_commits"
assert choices[0].value == "cz_conventional_commits"
assert choices[0].description == "<type>(<scope>): <subject>"
assert choices[1].title == "cz_customize"
assert choices[1].value == "cz_customize"
assert choices[1].description is None
assert choices[2].title == "cz_jira"
assert choices[2].value == "cz_jira"
assert (
choices[2].description
== "<ignored text> <ISSUE_KEY> <ignored text> #<COMMAND> <optional COMMAND_ARGUMENTS>"
)
choices = init._construct_name_choice_with_description()
assert len(choices) == 1
choice = choices[0]
assert choice.title == "cz_conventional_commits"
assert choice.value == "cz_conventional_commits"
assert choice.description == "<type>(<scope>): <subject>"