Skip to content

Commit f656350

Browse files
authored
Merge branch 'v4-9-0-test' into dev/sfusilier/exclamation_bc_cc
2 parents a7f9233 + f30ae2e commit f656350

18 files changed

+789
-499
lines changed

.pre-commit-config.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ repos:
2424
- id: debug-statements
2525
- id: no-commit-to-branch
2626
- id: check-merge-conflict
27-
- id: check-toml
27+
- id: check-toml # TOML linter (syntax checker)
2828
- id: check-yaml
2929
args: [ '--unsafe' ] # for mkdocs.yml
3030
- id: detect-private-key
@@ -55,17 +55,22 @@ repos:
5555
stages:
5656
- post-commit
5757

58+
- repo: https://github.com/ComPWA/taplo-pre-commit
59+
rev: v0.9.3
60+
hooks:
61+
- id: taplo-format
62+
5863
- repo: local
5964
hooks:
6065
- id: format
61-
name: Format
66+
name: Format Python code via Poetry
6267
language: system
6368
pass_filenames: false
6469
entry: poetry format
6570
types: [ python ]
6671

6772
- id: linter and test
68-
name: Linters
73+
name: Linters via Poetry
6974
language: system
7075
pass_filenames: false
7176
entry: poetry lint

.pre-commit-hooks.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@
2424
pass_filenames: false
2525
language: python
2626
language_version: python3
27-
minimum_pre_commit_version: "1.4.3"
27+
minimum_pre_commit_version: "3.2.0"

.taplo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include = ["pyproject.toml", ".taplo.toml"]
2+
3+
[formatting]
4+
indent_string = " "

commitizen/changelog.py

Lines changed: 47 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929

3030
import re
3131
from collections import OrderedDict, defaultdict
32-
from collections.abc import Generator, Iterable, Mapping, Sequence
32+
from collections.abc import Generator, Iterable, Mapping, MutableMapping, Sequence
3333
from dataclasses import dataclass
3434
from datetime import date
35+
from itertools import chain
3536
from typing import TYPE_CHECKING, Any
3637

3738
from jinja2 import (
@@ -88,33 +89,32 @@ def generate_tree_from_commits(
8889
pat = re.compile(changelog_pattern)
8990
map_pat = re.compile(commit_parser, re.MULTILINE)
9091
body_map_pat = re.compile(commit_parser, re.MULTILINE | re.DOTALL)
91-
current_tag: GitTag | None = None
9292
rules = rules or TagRules()
9393

9494
# Check if the latest commit is not tagged
95-
if commits:
96-
latest_commit = commits[0]
97-
current_tag = get_commit_tag(latest_commit, tags)
98-
99-
current_tag_name: str = unreleased_version or "Unreleased"
100-
current_tag_date: str = ""
101-
if unreleased_version is not None:
102-
current_tag_date = date.today().isoformat()
103-
if current_tag is not None and current_tag.name:
104-
current_tag_name = current_tag.name
105-
current_tag_date = current_tag.date
10695

96+
current_tag = get_commit_tag(commits[0], tags) if commits else None
97+
current_tag_name = unreleased_version or "Unreleased"
98+
current_tag_date = (
99+
date.today().isoformat() if unreleased_version is not None else ""
100+
)
101+
102+
used_tags: set[GitTag] = set()
103+
if current_tag:
104+
used_tags.add(current_tag)
105+
if current_tag.name:
106+
current_tag_name = current_tag.name
107+
current_tag_date = current_tag.date
108+
109+
commit_tag: GitTag | None = None
107110
changes: dict = defaultdict(list)
108-
used_tags: list = [current_tag]
109111
for commit in commits:
110-
commit_tag = get_commit_tag(commit, tags)
111-
112112
if (
113-
commit_tag
113+
(commit_tag := get_commit_tag(commit, tags))
114114
and commit_tag not in used_tags
115115
and rules.include_in_changelog(commit_tag)
116116
):
117-
used_tags.append(commit_tag)
117+
used_tags.add(commit_tag)
118118
release = {
119119
"version": current_tag_name,
120120
"date": current_tag_date,
@@ -127,24 +127,15 @@ def generate_tree_from_commits(
127127
current_tag_date = commit_tag.date
128128
changes = defaultdict(list)
129129

130-
matches = pat.match(commit.message)
131-
if not matches:
130+
if not pat.match(commit.message):
132131
continue
133132

134-
# Process subject from commit message
135-
if message := map_pat.match(commit.message):
136-
process_commit_message(
137-
changelog_message_builder_hook,
138-
message,
139-
commit,
140-
changes,
141-
change_type_map,
142-
)
143-
144-
# Process body from commit message
145-
body_parts = commit.body.split("\n\n")
146-
for body_part in body_parts:
147-
if message := body_map_pat.match(body_part):
133+
# Process subject and body from commit message
134+
for message in chain(
135+
[map_pat.match(commit.message)],
136+
(body_map_pat.match(block) for block in commit.body.split("\n\n")),
137+
):
138+
if message:
148139
process_commit_message(
149140
changelog_message_builder_hook,
150141
message,
@@ -167,8 +158,8 @@ def process_commit_message(
167158
hook: MessageBuilderHook | None,
168159
parsed: re.Match[str],
169160
commit: GitCommit,
170-
changes: dict[str | None, list],
171-
change_type_map: dict[str, str] | None = None,
161+
ref_changes: MutableMapping[str | None, list],
162+
change_type_map: Mapping[str, str] | None = None,
172163
) -> None:
173164
message: dict[str, Any] = {
174165
"sha1": commit.rev,
@@ -178,13 +169,16 @@ def process_commit_message(
178169
**parsed.groupdict(),
179170
}
180171

181-
if processed := hook(message, commit) if hook else message:
182-
messages = [processed] if isinstance(processed, dict) else processed
183-
for msg in messages:
184-
change_type = msg.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(msg)
172+
processed_msg = hook(message, commit) if hook else message
173+
if not processed_msg:
174+
return
175+
176+
messages = [processed_msg] if isinstance(processed_msg, dict) else processed_msg
177+
for msg in messages:
178+
change_type = msg.pop("change_type", None)
179+
if change_type_map:
180+
change_type = change_type_map.get(change_type, change_type)
181+
ref_changes[change_type].append(msg)
188182

189183

190184
def generate_ordered_changelog_tree(
@@ -251,6 +245,7 @@ def incremental_build(
251245
unreleased_start = metadata.unreleased_start
252246
unreleased_end = metadata.unreleased_end
253247
latest_version_position = metadata.latest_version_position
248+
254249
skip = False
255250
output_lines: list[str] = []
256251
for index, line in enumerate(lines):
@@ -260,9 +255,7 @@ def incremental_build(
260255
skip = False
261256
if (
262257
latest_version_position is None
263-
or isinstance(latest_version_position, int)
264-
and isinstance(unreleased_end, int)
265-
and latest_version_position > unreleased_end
258+
or latest_version_position > unreleased_end
266259
):
267260
continue
268261

@@ -271,13 +264,15 @@ def incremental_build(
271264

272265
if index == latest_version_position:
273266
output_lines.extend([new_content, "\n"])
274-
275267
output_lines.append(line)
276-
if not isinstance(latest_version_position, int):
277-
if output_lines and output_lines[-1].strip():
278-
# Ensure at least one blank line between existing and new content.
279-
output_lines.append("\n")
280-
output_lines.append(new_content)
268+
269+
if latest_version_position is not None:
270+
return output_lines
271+
272+
if output_lines and output_lines[-1].strip():
273+
# Ensure at least one blank line between existing and new content.
274+
output_lines.append("\n")
275+
output_lines.append(new_content)
281276
return output_lines
282277

283278

commitizen/cli.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,13 @@ def __call__(
5252
) -> None:
5353
if not isinstance(values, str):
5454
return
55-
if "=" not in values:
55+
56+
key, sep, value = values.partition("=")
57+
if not key or not sep:
5658
raise InvalidCommandArgumentError(
5759
f"Option {option_string} expect a key=value format"
5860
)
5961
kwargs = getattr(namespace, self.dest, None) or {}
60-
key, value = values.split("=", 1)
61-
if not key:
62-
raise InvalidCommandArgumentError(
63-
f"Option {option_string} expect a key=value format"
64-
)
6562
kwargs[key] = value.strip("'\"")
6663
setattr(namespace, self.dest, kwargs)
6764

@@ -583,20 +580,19 @@ def parse_no_raise(comma_separated_no_raise: str) -> list[int]:
583580
Receives digits and strings and outputs the parsed integer which
584581
represents the exit code found in exceptions.
585582
"""
586-
no_raise_items: list[str] = comma_separated_no_raise.split(",")
587-
no_raise_codes: list[int] = []
588-
for item in no_raise_items:
589-
if item.isdecimal():
590-
no_raise_codes.append(int(item))
591-
continue
583+
584+
def exit_code_from_str_or_skip(s: str) -> ExitCode | None:
592585
try:
593-
exit_code = ExitCode[item.strip()]
594-
except KeyError:
595-
out.warn(f"WARN: no_raise key `{item}` does not exist. Skipping.")
596-
continue
597-
else:
598-
no_raise_codes.append(exit_code.value)
599-
return no_raise_codes
586+
return ExitCode.from_str(s)
587+
except (KeyError, ValueError):
588+
out.warn(f"WARN: no_raise value `{s}` is not a valid exit code. Skipping.")
589+
return None
590+
591+
return [
592+
code.value
593+
for s in comma_separated_no_raise.split(",")
594+
if (code := exit_code_from_str_or_skip(s)) is not None
595+
]
600596

601597

602598
if TYPE_CHECKING:

commitizen/commands/bump.py

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
NoPatternMapError,
2424
NotAGitProjectError,
2525
NotAllowed,
26-
NoVersionSpecifiedError,
2726
)
2827
from commitizen.providers import get_provider
2928
from commitizen.tags import TagRules
@@ -163,11 +162,7 @@ def _find_increment(self, commits: list[git.GitCommit]) -> Increment | None:
163162
def __call__(self) -> None:
164163
"""Steps executed to bump."""
165164
provider = get_provider(self.config)
166-
167-
try:
168-
current_version = self.scheme(provider.get_version())
169-
except TypeError:
170-
raise NoVersionSpecifiedError()
165+
current_version = self.scheme(provider.get_version())
171166

172167
increment = self.arguments["increment"]
173168
prerelease = self.arguments["prerelease"]
@@ -177,36 +172,22 @@ def __call__(self) -> None:
177172
build_metadata = self.arguments["build_metadata"]
178173
get_next = self.arguments["get_next"]
179174
allow_no_commit = self.arguments["allow_no_commit"]
175+
major_version_zero = self.arguments["major_version_zero"]
180176

181177
if manual_version:
182-
if increment:
183-
raise NotAllowed("--increment cannot be combined with MANUAL_VERSION")
184-
185-
if prerelease:
186-
raise NotAllowed("--prerelease cannot be combined with MANUAL_VERSION")
187-
188-
if devrelease is not None:
189-
raise NotAllowed("--devrelease cannot be combined with MANUAL_VERSION")
190-
191-
if is_local_version:
192-
raise NotAllowed(
193-
"--local-version cannot be combined with MANUAL_VERSION"
194-
)
195-
196-
if build_metadata:
197-
raise NotAllowed(
198-
"--build-metadata cannot be combined with MANUAL_VERSION"
199-
)
200-
201-
if self.bump_settings["major_version_zero"]:
202-
raise NotAllowed(
203-
"--major-version-zero cannot be combined with MANUAL_VERSION"
204-
)
205-
206-
if get_next:
207-
raise NotAllowed("--get-next cannot be combined with MANUAL_VERSION")
208-
209-
if self.bump_settings["major_version_zero"] and current_version.release[0]:
178+
for val, option in (
179+
(increment, "--increment"),
180+
(prerelease, "--prerelease"),
181+
(devrelease is not None, "--devrelease"),
182+
(is_local_version, "--local-version"),
183+
(build_metadata, "--build-metadata"),
184+
(major_version_zero, "--major-version-zero"),
185+
(get_next, "--get-next"),
186+
):
187+
if val:
188+
raise NotAllowed(f"{option} cannot be combined with MANUAL_VERSION")
189+
190+
if major_version_zero and current_version.release[0]:
210191
raise NotAllowed(
211192
f"--major-version-zero is meaningless for current version {current_version}"
212193
)
@@ -215,11 +196,13 @@ def __call__(self) -> None:
215196
raise NotAllowed("--local-version cannot be combined with --build-metadata")
216197

217198
if get_next:
218-
# if trying to use --get-next, we should not allow --changelog or --changelog-to-stdout
219-
if self.changelog_flag or self.changelog_to_stdout:
220-
raise NotAllowed(
221-
"--changelog or --changelog-to-stdout is not allowed with --get-next"
222-
)
199+
for value, option in (
200+
(self.changelog_flag, "--changelog"),
201+
(self.changelog_to_stdout, "--changelog-to-stdout"),
202+
):
203+
if value:
204+
raise NotAllowed(f"{option} cannot be combined with --get-next")
205+
223206
# --get-next is a special case, taking precedence over config for 'update_changelog_on_bump'
224207
self.changelog_config = False
225208
# Setting dry_run to prevent any unwanted changes to the repo or files

0 commit comments

Comments
 (0)