|
31 | 31 | from collections import OrderedDict, defaultdict
|
32 | 32 | from dataclasses import dataclass
|
33 | 33 | from datetime import date
|
34 |
| -from typing import TYPE_CHECKING, Callable, Iterable |
| 34 | +from typing import TYPE_CHECKING, Iterable |
35 | 35 |
|
36 | 36 | from jinja2 import (
|
37 | 37 | BaseLoader,
|
|
52 | 52 | )
|
53 | 53 |
|
54 | 54 | if TYPE_CHECKING:
|
| 55 | + from commitizen.cz.base import MessageBuilderHook |
55 | 56 | from commitizen.version_schemes import VersionScheme
|
56 | 57 |
|
57 | 58 |
|
@@ -111,7 +112,7 @@ def generate_tree_from_commits(
|
111 | 112 | changelog_pattern: str,
|
112 | 113 | unreleased_version: str | None = None,
|
113 | 114 | change_type_map: dict[str, str] | None = None,
|
114 |
| - changelog_message_builder_hook: Callable | None = None, |
| 115 | + changelog_message_builder_hook: MessageBuilderHook | None = None, |
115 | 116 | merge_prerelease: bool = False,
|
116 | 117 | scheme: VersionScheme = DEFAULT_SCHEME,
|
117 | 118 | ) -> Iterable[dict]:
|
@@ -156,39 +157,48 @@ def generate_tree_from_commits(
|
156 | 157 | continue
|
157 | 158 |
|
158 | 159 | # Process subject from commit message
|
159 |
| - message = map_pat.match(commit.message) |
160 |
| - if message: |
161 |
| - parsed_message: dict = message.groupdict() |
162 |
| - |
163 |
| - if changelog_message_builder_hook: |
164 |
| - parsed_message = changelog_message_builder_hook(parsed_message, commit) |
165 |
| - if parsed_message: |
166 |
| - change_type = parsed_message.pop("change_type", None) |
167 |
| - if change_type_map: |
168 |
| - change_type = change_type_map.get(change_type, change_type) |
169 |
| - changes[change_type].append(parsed_message) |
| 160 | + if message := map_pat.match(commit.message): |
| 161 | + process_commit_message( |
| 162 | + changelog_message_builder_hook, |
| 163 | + message, |
| 164 | + commit, |
| 165 | + changes, |
| 166 | + change_type_map, |
| 167 | + ) |
170 | 168 |
|
171 | 169 | # Process body from commit message
|
172 | 170 | body_parts = commit.body.split("\n\n")
|
173 | 171 | for body_part in body_parts:
|
174 |
| - message_body = body_map_pat.match(body_part) |
175 |
| - if not message_body: |
176 |
| - continue |
177 |
| - parsed_message_body: dict = message_body.groupdict() |
178 |
| - |
179 |
| - if changelog_message_builder_hook: |
180 |
| - parsed_message_body = changelog_message_builder_hook( |
181 |
| - parsed_message_body, commit |
| 172 | + if message := body_map_pat.match(body_part): |
| 173 | + process_commit_message( |
| 174 | + changelog_message_builder_hook, |
| 175 | + message, |
| 176 | + commit, |
| 177 | + changes, |
| 178 | + change_type_map, |
182 | 179 | )
|
183 |
| - if parsed_message_body: |
184 |
| - change_type = parsed_message_body.pop("change_type", None) |
185 |
| - if change_type_map: |
186 |
| - change_type = change_type_map.get(change_type, change_type) |
187 |
| - changes[change_type].append(parsed_message_body) |
188 | 180 |
|
189 | 181 | yield {"version": current_tag_name, "date": current_tag_date, "changes": changes}
|
190 | 182 |
|
191 | 183 |
|
| 184 | +def process_commit_message( |
| 185 | + hook: MessageBuilderHook | None, |
| 186 | + parsed: re.Match[str], |
| 187 | + commit: GitCommit, |
| 188 | + changes: dict[str | None, list], |
| 189 | + change_type_map: dict[str, str] | None = None, |
| 190 | +): |
| 191 | + message: dict = parsed.groupdict() |
| 192 | + |
| 193 | + if processed := hook(message, commit) if hook else message: |
| 194 | + messages = [processed] if isinstance(processed, dict) else processed |
| 195 | + for msg in messages: |
| 196 | + change_type = msg.pop("change_type", None) |
| 197 | + if change_type_map: |
| 198 | + change_type = change_type_map.get(change_type, change_type) |
| 199 | + changes[change_type].append(msg) |
| 200 | + |
| 201 | + |
192 | 202 | def order_changelog_tree(tree: Iterable, change_type_order: list[str]) -> Iterable:
|
193 | 203 | if len(set(change_type_order)) != len(change_type_order):
|
194 | 204 | raise InvalidConfigurationError(
|
|
0 commit comments