From b69531494ca7c0c3191073eeeb6462ae2d2e3a9e Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 11:47:07 +0800 Subject: [PATCH 1/8] feat(cli): add example to _ask_name choice --- commitizen/commands/init.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 62678a2244..2baf5e1109 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -165,9 +165,20 @@ def _ask_config_path(self) -> Path: return Path(filename) def _ask_name(self) -> str: + + def construct_choice_with_example(cz_name: str) -> questionary.Choice: + cz_class = registry.get(cz_name) + if cz_class: + first_example = cz_class.example().splitlines()[0] + title = f"{cz_name}: {first_example}" + return questionary.Choice(title=title, value=cz_name) + return questionary.Choice(title=cz_name, value=cz_name) + name: str = questionary.select( "Please choose a cz (commit rule): (default: cz_conventional_commits)", - choices=list(registry.keys()), + choices=[ + construct_choice_with_example(cz_name) for cz_name in registry.keys() + ], default="cz_conventional_commits", style=self.cz.style, ).unsafe_ask() From 31247ee81af9851e5c19b25170e7ab57fcf4ed0d Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 12:20:36 +0800 Subject: [PATCH 2/8] fix: fix initialization error of BaseCommitizen in construct_choice_with_description --- commitizen/commands/init.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 2baf5e1109..db0ff31caa 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -11,7 +11,11 @@ from commitizen.config.factory import create_config from commitizen.cz import registry from commitizen.defaults import CONFIG_FILES, DEFAULT_SETTINGS -from commitizen.exceptions import InitFailedError, NoAnswersError +from commitizen.exceptions import ( + InitFailedError, + MissingCzCustomizeConfigError, + NoAnswersError, +) from commitizen.git import get_latest_tag_name, get_tag_names, smart_open from commitizen.version_schemes import KNOWN_SCHEMES, Version, get_version_scheme @@ -166,18 +170,20 @@ def _ask_config_path(self) -> Path: def _ask_name(self) -> str: - def construct_choice_with_example(cz_name: str) -> questionary.Choice: - cz_class = registry.get(cz_name) - if cz_class: - first_example = cz_class.example().splitlines()[0] - title = f"{cz_name}: {first_example}" - return questionary.Choice(title=title, value=cz_name) + def construct_choice_with_description(cz_name: str) -> questionary.Choice: + try: + cz_class = registry.get(cz_name)(self.config) + if cz_class: + first_example = cz_class.schema().partition("\n")[0] + return questionary.Choice(title=cz_name, value=cz_name, description=f"{first_example}") + except MissingCzCustomizeConfigError: + pass return questionary.Choice(title=cz_name, value=cz_name) name: str = questionary.select( "Please choose a cz (commit rule): (default: cz_conventional_commits)", choices=[ - construct_choice_with_example(cz_name) for cz_name in registry.keys() + construct_choice_with_description(cz_name) for cz_name in registry.keys() ], default="cz_conventional_commits", style=self.cz.style, From 88532dcb5dc973c485791605752e52101572f47b Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 12:25:31 +0800 Subject: [PATCH 3/8] chore: format code --- commitizen/commands/init.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index db0ff31caa..507d6992c8 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -13,7 +13,6 @@ from commitizen.defaults import CONFIG_FILES, DEFAULT_SETTINGS from commitizen.exceptions import ( InitFailedError, - MissingCzCustomizeConfigError, NoAnswersError, ) from commitizen.git import get_latest_tag_name, get_tag_names, smart_open @@ -169,21 +168,23 @@ def _ask_config_path(self) -> Path: return Path(filename) def _ask_name(self) -> str: - def construct_choice_with_description(cz_name: str) -> questionary.Choice: try: cz_class = registry.get(cz_name)(self.config) if cz_class: first_example = cz_class.schema().partition("\n")[0] - return questionary.Choice(title=cz_name, value=cz_name, description=f"{first_example}") - except MissingCzCustomizeConfigError: + return questionary.Choice( + title=cz_name, value=cz_name, description=f"{first_example}" + ) + except Exception: # pylint: disable=broad-except pass return questionary.Choice(title=cz_name, value=cz_name) name: str = questionary.select( "Please choose a cz (commit rule): (default: cz_conventional_commits)", choices=[ - construct_choice_with_description(cz_name) for cz_name in registry.keys() + construct_choice_with_description(cz_name) + for cz_name in registry.keys() ], default="cz_conventional_commits", style=self.cz.style, From aef017145e09647c41ae3cde0df35b648b6f9594 Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 12:45:24 +0800 Subject: [PATCH 4/8] fix: fix linting error --- commitizen/commands/init.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 507d6992c8..acfacd42a9 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -170,9 +170,10 @@ def _ask_config_path(self) -> Path: def _ask_name(self) -> str: def construct_choice_with_description(cz_name: str) -> questionary.Choice: try: - cz_class = registry.get(cz_name)(self.config) + cz_class = registry.get(cz_name) if cz_class: - first_example = cz_class.schema().partition("\n")[0] + cz_obj = cz_class(self.config) + first_example = cz_obj.schema().partition("\n")[0] return questionary.Choice( title=cz_name, value=cz_name, description=f"{first_example}" ) From c3c96356ac94cc4f509eb36892323dec087ff42a Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 13:22:54 +0800 Subject: [PATCH 5/8] fix: make the scope of try except smaller --- commitizen/commands/init.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index acfacd42a9..d71669b454 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -13,6 +13,7 @@ from commitizen.defaults import CONFIG_FILES, DEFAULT_SETTINGS from commitizen.exceptions import ( InitFailedError, + MissingCzCustomizeConfigError, NoAnswersError, ) from commitizen.git import get_latest_tag_name, get_tag_names, smart_open @@ -169,16 +170,16 @@ def _ask_config_path(self) -> Path: def _ask_name(self) -> str: def construct_choice_with_description(cz_name: str) -> questionary.Choice: - try: - cz_class = registry.get(cz_name) - if cz_class: + cz_class = registry.get(cz_name) + if cz_class: + try: cz_obj = cz_class(self.config) - first_example = cz_obj.schema().partition("\n")[0] - return questionary.Choice( - title=cz_name, value=cz_name, description=f"{first_example}" - ) - except Exception: # pylint: disable=broad-except - pass + except MissingCzCustomizeConfigError: + return questionary.Choice(title=cz_name, value=cz_name) + first_example = cz_obj.schema().partition("\n")[0] + return questionary.Choice( + title=cz_name, value=cz_name, description=first_example + ) return questionary.Choice(title=cz_name, value=cz_name) name: str = questionary.select( From 774ba6637a2527e1e7f7e81d3d80501699e62b91 Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 13:34:07 +0800 Subject: [PATCH 6/8] fix: better logic --- commitizen/commands/init.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index d71669b454..0c41487747 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -169,25 +169,25 @@ def _ask_config_path(self) -> Path: return Path(filename) def _ask_name(self) -> str: - def construct_choice_with_description(cz_name: str) -> questionary.Choice: - cz_class = registry.get(cz_name) - if cz_class: + def construct_choice_with_description() -> list[questionary.Choice]: + choices = [] + for cz_name, cz_class in registry.items(): try: cz_obj = cz_class(self.config) except MissingCzCustomizeConfigError: - return questionary.Choice(title=cz_name, value=cz_name) + choices.append(questionary.Choice(title=cz_name, value=cz_name)) + continue first_example = cz_obj.schema().partition("\n")[0] - return questionary.Choice( - title=cz_name, value=cz_name, description=first_example + choices.append( + questionary.Choice( + title=cz_name, value=cz_name, description=first_example + ) ) - return questionary.Choice(title=cz_name, value=cz_name) + return choices name: str = questionary.select( "Please choose a cz (commit rule): (default: cz_conventional_commits)", - choices=[ - construct_choice_with_description(cz_name) - for cz_name in registry.keys() - ], + choices=construct_choice_with_description(), default="cz_conventional_commits", style=self.cz.style, ).unsafe_ask() From aa68f324f66fc5d9de4936325dd0f91a22257fcf Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 14:27:31 +0800 Subject: [PATCH 7/8] chore: move construct_choice_with_description outside of _ask_name --- commitizen/commands/init.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 0c41487747..0773b71e42 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -169,30 +169,30 @@ def _ask_config_path(self) -> Path: return Path(filename) def _ask_name(self) -> str: - def construct_choice_with_description() -> list[questionary.Choice]: - choices = [] - for cz_name, cz_class in registry.items(): - try: - cz_obj = cz_class(self.config) - except MissingCzCustomizeConfigError: - choices.append(questionary.Choice(title=cz_name, value=cz_name)) - continue - first_example = cz_obj.schema().partition("\n")[0] - choices.append( - questionary.Choice( - title=cz_name, value=cz_name, description=first_example - ) - ) - return choices - name: str = questionary.select( "Please choose a cz (commit rule): (default: cz_conventional_commits)", - choices=construct_choice_with_description(), + choices=self._construct_name_choice_with_description(), default="cz_conventional_commits", style=self.cz.style, ).unsafe_ask() return name + def _construct_name_choice_with_description(self) -> list[questionary.Choice]: + choices = [] + for cz_name, cz_class in registry.items(): + try: + cz_obj = cz_class(self.config) + except MissingCzCustomizeConfigError: + choices.append(questionary.Choice(title=cz_name, value=cz_name)) + continue + first_example = cz_obj.schema().partition("\n")[0] + choices.append( + questionary.Choice( + title=cz_name, value=cz_name, description=first_example + ) + ) + return choices + def _ask_tag(self) -> str: latest_tag = get_latest_tag_name() if not latest_tag: From 13c9303334533a4695f32a6081ff1c0c030dbbe7 Mon Sep 17 00:00:00 2001 From: "andre.liang" Date: Sat, 31 Jan 2026 14:27:56 +0800 Subject: [PATCH 8/8] test: add unittest for _construct_name_choice_with_description( --- tests/commands/test_init_command.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/commands/test_init_command.py b/tests/commands/test_init_command.py index 8398e784bc..0529553cf2 100644 --- a/tests/commands/test_init_command.py +++ b/tests/commands/test_init_command.py @@ -10,6 +10,7 @@ from commitizen import cmd, commands from commitizen.__version__ import __version__ +from commitizen.cz import registry from commitizen.exceptions import InitFailedError, NoAnswersError if TYPE_CHECKING: @@ -462,3 +463,22 @@ def test_init_configuration_with_version_provider( assert ( "version = " not in config_data ) # Version should not be set when using version_provider + + +def test_construct_name_choice_with_description( + config: BaseConfig, mocker: MockFixture +): + """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 = 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 == "(): "