Skip to content

Commit ffe4744

Browse files
author
Amit Levy
committed
feat(ConventionalCommitsCz): allow to override defaults from config
Before fixing tests and adding extra ones, I would like to received partial feedback about my changes to see if this aligns with the desired code changes by maintainers. As addressed on commitizen-tools#535, when using customize commitizen, if we want to customize a small attribute, we need to redefine all commitizens options to make our custom class work. For example: ```diff diff --git a/cz.yaml b/cz.yaml index f2e19a9..302e961 100644 --- a/cz.yaml +++ b/cz.yaml @@ -1,6 +1,18 @@ commitizen: annotated_tag: true bump_message: 'bump: $current_version -> $new_version [skip ci]' - name: cz_conventional_commits + name: cz_customize update_changelog_on_bump: true version: 0.11.0 + + customize: + bump_pattern: '^(fix|feat|docs|style|refactor|test|build|ci)' + bump_map: + fix: PATCH + feat: PATCH + docs: PATCH + style: PATCH + refactor: PATCH + test: PATCH + build: PATCH + ci: PATCH diff --git a/t b/t new file mode 100644 index 0000000..e69de29 diff --git a/t2 b/t2 new file mode 100644 index 0000000..e69de29 ``` making the following change on a repo would cause an unexpected behavior: ```python + bash -c cz commit Traceback (most recent call last): File "/home/amit/.local/bin/cz", line 8, in <module> sys.exit(main()) File "/home/amit/.local/lib/python3.10/site-packages/commitizen/cli.py", line 382, in main args.func(conf, vars(args))() File "/home/amit/.local/lib/python3.10/site-packages/commitizen/commands/commit.py", line 74, in __call__ m = self.prompt_commit_questions() File "/home/amit/.local/lib/python3.10/site-packages/commitizen/commands/commit.py", line 49, in prompt_commit_questions for question in filter(lambda q: q["type"] == "list", questions): File "/home/amit/.local/lib/python3.10/site-packages/commitizen/commands/commit.py", line 49, in <lambda> for question in filter(lambda q: q["type"] == "list", questions): KeyError: 'type' ``` From my best understanding, this error happens because I didn't defined question section in config, though I'm ok with using ConventionalCommitsCz default ones. This commit extends ConventionalCommitsCz to read from config and fallbacks to defaults if some are not provided. By adding this change, potentially customize commitizen can be deprecated. BREAKING CHANGES: CustomizeCommitsCz was removed. Closes commitizen-tools#535.
1 parent 2ff9f15 commit ffe4744

File tree

3 files changed

+86
-51
lines changed

3 files changed

+86
-51
lines changed

commitizen/cz/base.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,14 @@
11
from abc import ABCMeta, abstractmethod
2-
from typing import Callable, Dict, List, Optional, Tuple
2+
from typing import Callable, Dict, List, Optional
33

44
from prompt_toolkit.styles import Style, merge_styles
55

6-
from commitizen import git
6+
from commitizen import defaults, git
77
from commitizen.config.base_config import BaseConfig
88
from commitizen.defaults import Questions
99

1010

1111
class BaseCommitizen(metaclass=ABCMeta):
12-
bump_pattern: Optional[str] = None
13-
bump_map: Optional[Dict[str, str]] = None
14-
default_style_config: List[Tuple[str, str]] = [
15-
("qmark", "fg:#ff9d00 bold"),
16-
("question", "bold"),
17-
("answer", "fg:#ff9d00 bold"),
18-
("pointer", "fg:#ff9d00 bold"),
19-
("highlighted", "fg:#ff9d00 bold"),
20-
("selected", "fg:#cc5454"),
21-
("separator", "fg:#cc5454"),
22-
("instruction", ""),
23-
("text", ""),
24-
("disabled", "fg:#858585 italic"),
25-
]
26-
27-
# The whole subject will be parsed as message by default
28-
# This allows supporting changelog for any rule system.
29-
# It can be modified per rule
30-
commit_parser: Optional[str] = r"(?P<message>.*)"
31-
changelog_pattern: Optional[str] = r".*"
32-
change_type_map: Optional[Dict[str, str]] = None
33-
change_type_order: Optional[List[str]] = None
34-
3512
# Executed per message parsed by the commitizen
3613
changelog_message_builder_hook: Optional[
3714
Callable[[Dict, git.GitCommit], Dict]
@@ -40,10 +17,34 @@ class BaseCommitizen(metaclass=ABCMeta):
4017
# Executed only at the end of the changelog generation
4118
changelog_hook: Optional[Callable[[str, Optional[str]], str]] = None
4219

20+
default_style_config = defaults.default_style_config
21+
4322
def __init__(self, config: BaseConfig):
4423
self.config = config
45-
if not self.config.settings.get("style"):
46-
self.config.settings.update({"style": BaseCommitizen.default_style_config})
24+
self.default_style_config: Optional[Dict[str, str]] = self.config.settings.get(
25+
"default_style_config", defaults.default_style_config
26+
)
27+
self.bump_pattern: Optional[str] = self.config.settings.get(
28+
"bump_pattern", defaults.bump_pattern
29+
)
30+
self.bump_map: Optional[Dict[str, str]] = self.config.settings.get(
31+
"bump_map", defaults.bump_map
32+
)
33+
self.change_type_order: Optional[List[str]] = self.config.settings.get(
34+
"change_type_order", defaults.change_type_order
35+
)
36+
self.change_type_map: Optional[Dict[str, str]] = self.config.settings.get(
37+
"change_type_map", defaults.change_type_map
38+
)
39+
self.commit_parser: Optional[str] = self.config.settings.get(
40+
"commit_parser", defaults.commit_parser
41+
)
42+
self.changelog_pattern: Optional[str] = self.config.settings.get(
43+
"changelog_pattern", defaults.changelog_pattern
44+
)
45+
self.version_parser = self.config.settings.get(
46+
"version_parser", defaults.version_parser
47+
)
4748

4849
@abstractmethod
4950
def questions(self) -> Questions:
@@ -58,7 +59,7 @@ def style(self):
5859
return merge_styles(
5960
[
6061
Style(BaseCommitizen.default_style_config),
61-
Style(self.config.settings["style"]),
62+
Style(self.default_style_config),
6263
]
6364
)
6465

commitizen/cz/conventional_commits/conventional_commits.py

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import os
22
import re
33

4-
from commitizen import defaults
4+
try:
5+
from jinja2 import Template
6+
except ImportError:
7+
from string import Template # type: ignore
8+
59
from commitizen.cz.base import BaseCommitizen
610
from commitizen.cz.utils import multiple_line_breaker, required_validator
711
from commitizen.defaults import Questions
@@ -28,18 +32,6 @@ def parse_subject(text):
2832

2933

3034
class ConventionalCommitsCz(BaseCommitizen):
31-
bump_pattern = defaults.bump_pattern
32-
bump_map = defaults.bump_map
33-
commit_parser = defaults.commit_parser
34-
version_parser = defaults.version_parser
35-
change_type_map = {
36-
"feat": "Feat",
37-
"fix": "Fix",
38-
"refactor": "Refactor",
39-
"perf": "Perf",
40-
}
41-
changelog_pattern = defaults.bump_pattern
42-
4335
def questions(self) -> Questions:
4436
questions: Questions = [
4537
{
@@ -148,9 +140,21 @@ def questions(self) -> Questions:
148140
),
149141
},
150142
]
151-
return questions
143+
144+
# TODO: How would filter functions would be handled from config?
145+
return self.config.settings.get("questions", questions)
152146

153147
def message(self, answers: dict) -> str:
148+
custom_message = self.config.settings.get("message_template")
149+
if custom_message:
150+
message_template = Template(
151+
self.config.settings.get("message_template", "")
152+
)
153+
if getattr(Template, "substitute", None):
154+
return message_template.substitute(**answers) # type: ignore
155+
else:
156+
return message_template.render(**answers)
157+
154158
prefix = answers["prefix"]
155159
scope = answers["scope"]
156160
subject = answers["subject"]
@@ -172,39 +176,47 @@ def message(self, answers: dict) -> str:
172176
return message
173177

174178
def example(self) -> str:
175-
return (
179+
return self.config.settings.get(
180+
"example",
176181
"fix: correct minor typos in code\n"
177182
"\n"
178183
"see the issue for details on the typos fixed\n"
179184
"\n"
180-
"closes issue #12"
185+
"closes issue #12",
181186
)
182187

183188
def schema(self) -> str:
184-
return (
189+
return self.config.settings.get(
190+
"schema",
185191
"<type>(<scope>): <subject>\n"
186192
"<BLANK LINE>\n"
187193
"<body>\n"
188194
"<BLANK LINE>\n"
189-
"(BREAKING CHANGE: )<footer>"
195+
"(BREAKING CHANGE: )<footer>",
190196
)
191197

192198
def schema_pattern(self) -> str:
193199
PATTERN = (
194-
r"(?s)" # To explictly make . match new line
200+
r"(?s)" # To explicitly make . match new line
195201
r"(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert|bump)" # type
196202
r"(\(\S+\))?!?:" # scope
197203
r"( [^\n\r]+)" # subject
198204
r"((\n\n.*)|(\s*))?$"
199205
)
200-
return PATTERN
206+
return self.config.settings.get("schema_pattern", PATTERN)
201207

202208
def info(self) -> str:
203209
dir_path = os.path.dirname(os.path.realpath(__file__))
204210
filepath = os.path.join(dir_path, "conventional_commits_info.txt")
205-
with open(filepath, "r") as f:
206-
content = f.read()
207-
return content
211+
info_path = self.config.settings.get("info_path", filepath)
212+
info = self.config.settings.get("info")
213+
if info_path:
214+
with open(info_path, "r") as f:
215+
content = f.read()
216+
return content
217+
elif info:
218+
return info
219+
return None
208220

209221
def process_commit(self, commit: str) -> str:
210222
pat = re.compile(self.schema_pattern())

commitizen/defaults.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,25 @@ class Settings(TypedDict, total=False):
8787

8888
commit_parser = r"^(?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?:\s(?P<message>.*)?" # noqa
8989
version_parser = r"(?P<version>([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?(\w+)?)"
90+
91+
change_type_map = {
92+
"feat": "Feat",
93+
"fix": "Fix",
94+
"refactor": "Refactor",
95+
"perf": "Perf",
96+
}
97+
98+
changelog_pattern = r".*"
99+
100+
default_style_config: List[Tuple[str, str]] = [
101+
("qmark", "fg:#ff9d00 bold"),
102+
("question", "bold"),
103+
("answer", "fg:#ff9d00 bold"),
104+
("pointer", "fg:#ff9d00 bold"),
105+
("highlighted", "fg:#ff9d00 bold"),
106+
("selected", "fg:#cc5454"),
107+
("separator", "fg:#cc5454"),
108+
("instruction", ""),
109+
("text", ""),
110+
("disabled", "fg:#858585 italic"),
111+
]

0 commit comments

Comments
 (0)