diff --git a/commitizen/commands/commit.py b/commitizen/commands/commit.py index eedf77e079..98582619a6 100644 --- a/commitizen/commands/commit.py +++ b/commitizen/commands/commit.py @@ -52,7 +52,7 @@ def prompt_commit_questions(self) -> str: # Prompt user for the commit message cz = self.cz questions = cz.questions() - for question in filter(lambda q: q["type"] == "list", questions): + for question in (q for q in questions if q["type"] == "list"): question["use_shortcuts"] = self.config.settings["use_shortcuts"] try: answers = questionary.prompt(questions, style=cz.style) diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index 43455a74ca..06d03c12b5 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -9,7 +9,7 @@ from commitizen import git from commitizen.config.base_config import BaseConfig -from commitizen.defaults import Questions +from commitizen.question import CzQuestion class MessageBuilderHook(Protocol): @@ -68,7 +68,7 @@ def __init__(self, config: BaseConfig) -> None: self.config.settings.update({"style": BaseCommitizen.default_style_config}) @abstractmethod - def questions(self) -> Questions: + def questions(self) -> Iterable[CzQuestion]: """Questions regarding the commit message.""" @abstractmethod diff --git a/commitizen/cz/conventional_commits/conventional_commits.py b/commitizen/cz/conventional_commits/conventional_commits.py index 9a2b9016b7..d8c05fa94e 100644 --- a/commitizen/cz/conventional_commits/conventional_commits.py +++ b/commitizen/cz/conventional_commits/conventional_commits.py @@ -4,7 +4,7 @@ from commitizen import defaults from commitizen.cz.base import BaseCommitizen from commitizen.cz.utils import multiple_line_breaker, required_validator -from commitizen.defaults import Questions +from commitizen.question import CzQuestion __all__ = ["ConventionalCommitsCz"] @@ -40,7 +40,7 @@ class ConventionalCommitsCz(BaseCommitizen): } changelog_pattern = defaults.BUMP_PATTERN - def questions(self) -> Questions: + def questions(self) -> list[CzQuestion]: return [ { "type": "list", @@ -133,8 +133,8 @@ def questions(self) -> Questions: }, { "type": "confirm", - "message": "Is this a BREAKING CHANGE? Correlates with MAJOR in SemVer", "name": "is_breaking_change", + "message": "Is this a BREAKING CHANGE? Correlates with MAJOR in SemVer", "default": False, }, { diff --git a/commitizen/cz/customize/customize.py b/commitizen/cz/customize/customize.py index 53ada4b2c0..0b60b84189 100644 --- a/commitizen/cz/customize/customize.py +++ b/commitizen/cz/customize/customize.py @@ -2,6 +2,8 @@ from typing import TYPE_CHECKING +from commitizen.question import CzQuestion + if TYPE_CHECKING: from jinja2 import Template else: @@ -14,7 +16,6 @@ from commitizen import defaults from commitizen.config import BaseConfig from commitizen.cz.base import BaseCommitizen -from commitizen.defaults import Questions from commitizen.exceptions import MissingCzCustomizeConfigError __all__ = ["CustomizeCommitsCz"] @@ -45,8 +46,8 @@ def __init__(self, config: BaseConfig): if value := self.custom_settings.get(attr_name): setattr(self, attr_name, value) - def questions(self) -> Questions: - return self.custom_settings.get("questions", [{}]) + def questions(self) -> list[CzQuestion]: + return self.custom_settings.get("questions", [{}]) # type: ignore def message(self, answers: dict) -> str: message_template = Template(self.custom_settings.get("message_template", "")) diff --git a/commitizen/cz/jira/jira.py b/commitizen/cz/jira/jira.py index f43de2177c..7d3f74d303 100644 --- a/commitizen/cz/jira/jira.py +++ b/commitizen/cz/jira/jira.py @@ -1,13 +1,13 @@ import os from commitizen.cz.base import BaseCommitizen -from commitizen.defaults import Questions +from commitizen.question import CzQuestion __all__ = ["JiraSmartCz"] class JiraSmartCz(BaseCommitizen): - def questions(self) -> Questions: + def questions(self) -> list[CzQuestion]: return [ { "type": "input", diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 10d55b8621..977176d3bd 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -6,8 +6,10 @@ from collections.abc import Iterable, MutableMapping, Sequence from typing import Any, TypedDict +from commitizen.question import CzQuestion + # Type -Questions = Iterable[MutableMapping[str, Any]] +Questions = Iterable[MutableMapping[str, Any]] # TODO: deprecate this? class CzSettings(TypedDict, total=False): @@ -16,7 +18,7 @@ class CzSettings(TypedDict, total=False): bump_map_major_version_zero: OrderedDict[str, str] change_type_order: list[str] - questions: Questions + questions: Iterable[CzQuestion] example: str | None schema_pattern: str | None schema: str | None diff --git a/commitizen/question.py b/commitizen/question.py new file mode 100644 index 0000000000..393e386092 --- /dev/null +++ b/commitizen/question.py @@ -0,0 +1,32 @@ +from typing import Callable, Literal, TypedDict, Union + + +class Choice(TypedDict, total=False): + value: str + name: str + key: str + + +class ListQuestion(TypedDict, total=False): + type: Literal["list"] + name: str + message: str + choices: list[Choice] + use_shortcuts: bool + + +class InputQuestion(TypedDict, total=False): + type: Literal["input"] + name: str + message: str + filter: Callable[[str], str] + + +class ConfirmQuestion(TypedDict): + type: Literal["confirm"] + name: str + message: str + default: bool + + +CzQuestion = Union[ListQuestion, InputQuestion, ConfirmQuestion] diff --git a/tests/conftest.py b/tests/conftest.py index 60c586f2e6..1959d09840 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,6 +17,7 @@ from commitizen.config import BaseConfig from commitizen.cz import registry from commitizen.cz.base import BaseCommitizen +from commitizen.question import CzQuestion from tests.utils import create_file_and_commit SIGNER = "GitHub Action" @@ -222,7 +223,7 @@ def use_cz_semver(mocker): class MockPlugin(BaseCommitizen): - def questions(self) -> defaults.Questions: + def questions(self) -> list[CzQuestion]: return [] def message(self, answers: dict) -> str: