Skip to content

Commit db902f9

Browse files
authored
Merge branch 'v4-9-0-test' into feat/Add-config-option-for-line-length-warning
2 parents af6aa62 + 69db5b4 commit db902f9

File tree

13 files changed

+747
-496
lines changed

13 files changed

+747
-496
lines changed

.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"

commitizen/changelog.py

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
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,

commitizen/cli.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,13 @@ def __call__(
470470
"help": "a range of git rev to check. e.g, master..HEAD",
471471
"exclusive_group": "group1",
472472
},
473+
{
474+
"name": ["-d", "--use-default-range"],
475+
"action": "store_true",
476+
"default": False,
477+
"help": "check from the default branch to HEAD. e.g, refs/remotes/origin/master..HEAD",
478+
"exclusive_group": "group1",
479+
},
473480
{
474481
"name": ["-m", "--message"],
475482
"help": "commit message that needs to be checked",

commitizen/commands/check.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class CheckArgs(TypedDict, total=False):
2222
message_length_limit: int | None
2323
allowed_prefixes: list[str]
2424
message: str
25+
use_default_range: bool
2526

2627

2728
class Check:
@@ -41,7 +42,7 @@ def __init__(self, config: BaseConfig, arguments: CheckArgs, *args: object) -> N
4142
self.allow_abort = bool(
4243
arguments.get("allow_abort", config.settings["allow_abort"])
4344
)
44-
45+
self.use_default_range = bool(arguments.get("use_default_range"))
4546
self.max_msg_length = arguments.get(
4647
"message_length_limit", config.settings.get("message_length_limit", None)
4748
)
@@ -54,25 +55,28 @@ def __init__(self, config: BaseConfig, arguments: CheckArgs, *args: object) -> N
5455
else config.settings["allowed_prefixes"]
5556
)
5657

57-
self._valid_command_argument()
58-
59-
self.config: BaseConfig = config
60-
self.encoding = config.settings["encoding"]
61-
self.cz = factory.committer_factory(self.config)
62-
63-
def _valid_command_argument(self) -> None:
6458
num_exclusive_args_provided = sum(
6559
arg is not None
66-
for arg in (self.commit_msg_file, self.commit_msg, self.rev_range)
60+
for arg in (
61+
self.commit_msg_file,
62+
self.commit_msg,
63+
self.rev_range,
64+
)
6765
)
68-
if num_exclusive_args_provided == 0 and not sys.stdin.isatty():
69-
self.commit_msg = sys.stdin.read()
70-
elif num_exclusive_args_provided != 1:
66+
67+
if num_exclusive_args_provided > 1:
7168
raise InvalidCommandArgumentError(
7269
"Only one of --rev-range, --message, and --commit-msg-file is permitted by check command! "
7370
"See 'cz check -h' for more information"
7471
)
7572

73+
if num_exclusive_args_provided == 0 and not sys.stdin.isatty():
74+
self.commit_msg = sys.stdin.read()
75+
76+
self.config: BaseConfig = config
77+
self.encoding = config.settings["encoding"]
78+
self.cz = factory.committer_factory(self.config)
79+
7680
def __call__(self) -> None:
7781
"""Validate if commit messages follows the conventional pattern.
7882
@@ -113,7 +117,10 @@ def _get_commits(self) -> list[git.GitCommit]:
113117
return [git.GitCommit(rev="", title="", body=self._filter_comments(msg))]
114118

115119
# Get commit messages from git log (--rev-range)
116-
return git.get_commits(end=self.rev_range)
120+
return git.get_commits(
121+
git.get_default_branch() if self.use_default_range else None,
122+
self.rev_range,
123+
)
117124

118125
@staticmethod
119126
def _filter_comments(msg: str) -> str:
@@ -138,7 +145,7 @@ def _filter_comments(msg: str) -> str:
138145
The filtered commit message without comments.
139146
"""
140147

141-
lines = []
148+
lines: list[str] = []
142149
for line in msg.split("\n"):
143150
if "# ------------------------ >8 ------------------------" in line:
144151
break

commitizen/commands/init.py

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,6 @@ def is_npm_package(self) -> bool:
111111
def is_php_composer(self) -> bool:
112112
return os.path.isfile("composer.json")
113113

114-
@property
115-
def latest_tag(self) -> str | None:
116-
return get_latest_tag_name()
117-
118-
def tags(self) -> list | None:
119-
"""Not a property, only use if necessary"""
120-
if self.latest_tag is None:
121-
return None
122-
return get_tag_names()
123-
124114
@property
125115
def is_pre_commit_installed(self) -> bool:
126116
return bool(shutil.which("pre-commit"))
@@ -142,8 +132,8 @@ def __call__(self) -> None:
142132

143133
out.info("Welcome to commitizen!\n")
144134
out.line(
145-
"Answer the questions to configure your project.\n"
146-
"For further configuration visit:\n"
135+
"Answer the following questions to configure your project.\n"
136+
"For further configuration, visit:\n"
147137
"\n"
148138
"https://commitizen-tools.github.io/commitizen/config/"
149139
"\n"
@@ -170,21 +160,6 @@ def __call__(self) -> None:
170160
self.config = JsonConfig(data="{}", path=config_path)
171161
elif "yaml" in config_path:
172162
self.config = YAMLConfig(data="", path=config_path)
173-
values_to_add: dict[str, Any] = {}
174-
values_to_add["name"] = cz_name
175-
values_to_add["tag_format"] = tag_format
176-
values_to_add["version_scheme"] = version_scheme
177-
178-
if version_provider == "commitizen":
179-
values_to_add["version"] = version.public
180-
else:
181-
values_to_add["version_provider"] = version_provider
182-
183-
if update_changelog_on_bump:
184-
values_to_add["update_changelog_on_bump"] = update_changelog_on_bump
185-
186-
if major_version_zero:
187-
values_to_add["major_version_zero"] = major_version_zero
188163

189164
# Collect hook data
190165
hook_types = questionary.checkbox(
@@ -202,7 +177,18 @@ def __call__(self) -> None:
202177

203178
# Create and initialize config
204179
self.config.init_empty_config_content()
205-
self._update_config_file(values_to_add)
180+
181+
self.config.set_key("name", cz_name)
182+
self.config.set_key("tag_format", tag_format)
183+
self.config.set_key("version_scheme", version_scheme)
184+
if version_provider == "commitizen":
185+
self.config.set_key("version", version.public)
186+
else:
187+
self.config.set_key("version_provider", version_provider)
188+
if update_changelog_on_bump:
189+
self.config.set_key("update_changelog_on_bump", update_changelog_on_bump)
190+
if major_version_zero:
191+
self.config.set_key("major_version_zero", major_version_zero)
206192

207193
out.write("\nYou can bump the version running:\n")
208194
out.info("\tcz bump\n")
@@ -231,31 +217,32 @@ def _ask_name(self) -> str:
231217
return name
232218

233219
def _ask_tag(self) -> str:
234-
latest_tag = self.project_info.latest_tag
220+
latest_tag = get_latest_tag_name()
235221
if not latest_tag:
236222
out.error("No Existing Tag. Set tag to v0.0.1")
237223
return "0.0.1"
238224

239-
is_correct_tag = questionary.confirm(
225+
if questionary.confirm(
240226
f"Is {latest_tag} the latest tag?", style=self.cz.style, default=False
227+
).unsafe_ask():
228+
return latest_tag
229+
230+
existing_tags = get_tag_names()
231+
if not existing_tags:
232+
out.error("No Existing Tag. Set tag to v0.0.1")
233+
return "0.0.1"
234+
235+
answer: str = questionary.select(
236+
"Please choose the latest tag: ",
237+
# The latest tag is most likely with the largest number.
238+
# Thus, listing the existing_tags in reverse order makes more sense.
239+
choices=sorted(existing_tags, reverse=True),
240+
style=self.cz.style,
241241
).unsafe_ask()
242-
if not is_correct_tag:
243-
tags = self.project_info.tags()
244-
if not tags:
245-
out.error("No Existing Tag. Set tag to v0.0.1")
246-
return "0.0.1"
247-
248-
# the latest tag is most likely with the largest number. Thus list the tags in reverse order makes more sense
249-
sorted_tags = sorted(tags, reverse=True)
250-
latest_tag = questionary.select(
251-
"Please choose the latest tag: ",
252-
choices=sorted_tags,
253-
style=self.cz.style,
254-
).unsafe_ask()
255-
256-
if not latest_tag:
257-
raise NoAnswersError("Tag is required!")
258-
return latest_tag
242+
243+
if not answer:
244+
raise NoAnswersError("Tag is required!")
245+
return answer
259246

260247
def _ask_tag_format(self, latest_tag: str) -> str:
261248
if latest_tag.startswith("v"):
@@ -360,7 +347,7 @@ def _get_config_data(self) -> dict[str, Any]:
360347
"rev": f"v{__version__}",
361348
"hooks": [
362349
{"id": "commitizen"},
363-
{"id": "commitizen-branch", "stages": ["push"]},
350+
{"id": "commitizen-branch", "stages": ["pre-push"]},
364351
],
365352
}
366353

@@ -396,7 +383,3 @@ def _install_pre_commit_hook(self, hook_types: list[str] | None = None) -> None:
396383
hook_types = ["commit-msg", "pre-push"]
397384
self._exec_install_pre_commit_hook(hook_types)
398385
out.write("commitizen pre-commit hook is now installed in your '.git'\n")
399-
400-
def _update_config_file(self, values: dict[str, Any]) -> None:
401-
for key, value in values.items():
402-
self.config.set_key(key, value)

commitizen/git.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ class GitObject:
4949
def __eq__(self, other: object) -> bool:
5050
return hasattr(other, "rev") and self.rev == other.rev
5151

52+
def __hash__(self) -> int:
53+
return hash(self.rev)
54+
5255

5356
class GitCommit(GitObject):
5457
def __init__(
@@ -329,3 +332,10 @@ def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]:
329332
if c.return_code != 0:
330333
raise GitCommandError(c.err)
331334
return c.out.split(f"{delimiter}\n")
335+
336+
337+
def get_default_branch() -> str:
338+
c = cmd.run("git symbolic-ref refs/remotes/origin/HEAD")
339+
if c.return_code != 0:
340+
raise GitCommandError(c.err)
341+
return c.out.strip()

0 commit comments

Comments
 (0)