commitizen 4.18.1__tar.gz → 4.19.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commitizen-4.18.1 → commitizen-4.19.1}/PKG-INFO +1 -1
- commitizen-4.19.1/commitizen/__version__.py +1 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/bump.py +4 -50
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/bump.py +14 -2
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/changelog.py +1 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/version.py +14 -3
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/base.py +48 -2
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/conventional_commits.py +6 -2
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/customize.py +6 -4
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/defaults.py +2 -2
- commitizen-4.19.1/commitizen/version_increment.py +151 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/pyproject.toml +1 -2
- {commitizen-4.18.1 → commitizen-4.19.1}/pyproject.toml.orig +1 -2
- commitizen-4.18.1/commitizen/__version__.py +0 -1
- commitizen-4.18.1/commitizen/version_increment.py +0 -33
- {commitizen-4.18.1 → commitizen-4.19.1}/LICENSE +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/__main__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/asciidoc.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/base.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/markdown.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/restructuredtext.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/textile.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cli.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cmd.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/check.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/commit.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/example.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/info.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/init.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/list_cz.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/schema.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/base_config.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/factory.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/json_config.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/toml_config.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/yaml_config.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/conventional_commits_info.txt +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/customize_info.txt +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/exceptions.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/jira.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/jira_info.txt +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/utils.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/exceptions.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/factory.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/git.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/hooks.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/out.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/project_info.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/__init__.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/base_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/cargo_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/commitizen_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/composer_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/npm_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/pep621_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/poetry_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/scm_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/uv_provider.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/py.typed +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/question.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/tags.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.adoc.j2 +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.md.j2 +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.rst.j2 +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.textile.j2 +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/version_schemes.py +0 -0
- {commitizen-4.18.1 → commitizen-4.19.1}/docs/README.md +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.19.1"
|
|
@@ -2,64 +2,18 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import re
|
|
5
|
-
from collections import OrderedDict
|
|
6
5
|
from glob import iglob
|
|
7
|
-
from logging import getLogger
|
|
8
6
|
from string import Template
|
|
9
|
-
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
10
8
|
|
|
11
|
-
from commitizen.defaults import BUMP_MESSAGE
|
|
9
|
+
from commitizen.defaults import BUMP_MESSAGE
|
|
12
10
|
from commitizen.exceptions import CurrentVersionNotFoundError
|
|
13
|
-
from commitizen.git import
|
|
11
|
+
from commitizen.git import smart_open
|
|
14
12
|
|
|
15
13
|
if TYPE_CHECKING:
|
|
16
14
|
from collections.abc import Generator, Iterable
|
|
17
15
|
|
|
18
|
-
from commitizen.version_schemes import
|
|
19
|
-
|
|
20
|
-
VERSION_TYPES = [None, PATCH, MINOR, MAJOR]
|
|
21
|
-
|
|
22
|
-
logger = getLogger("commitizen")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def find_increment(
|
|
26
|
-
commits: list[GitCommit], regex: str, increments_map: dict | OrderedDict
|
|
27
|
-
) -> Increment | None:
|
|
28
|
-
if isinstance(increments_map, dict):
|
|
29
|
-
increments_map = OrderedDict(increments_map)
|
|
30
|
-
|
|
31
|
-
# Most important cases are major and minor.
|
|
32
|
-
# Everything else will be considered patch.
|
|
33
|
-
select_pattern = re.compile(regex)
|
|
34
|
-
increment: str | None = None
|
|
35
|
-
|
|
36
|
-
for commit in commits:
|
|
37
|
-
for message in commit.message.split("\n"):
|
|
38
|
-
result = select_pattern.search(message)
|
|
39
|
-
|
|
40
|
-
if result:
|
|
41
|
-
found_keyword = result.group(1)
|
|
42
|
-
new_increment = None
|
|
43
|
-
for match_pattern in increments_map.keys():
|
|
44
|
-
if re.match(match_pattern, found_keyword):
|
|
45
|
-
new_increment = increments_map[match_pattern]
|
|
46
|
-
break
|
|
47
|
-
|
|
48
|
-
if new_increment is None:
|
|
49
|
-
logger.debug(
|
|
50
|
-
f"no increment needed for '{found_keyword}' in '{message}'"
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
if VERSION_TYPES.index(increment) < VERSION_TYPES.index(new_increment):
|
|
54
|
-
logger.debug(
|
|
55
|
-
f"increment detected is '{new_increment}' due to '{found_keyword}' in '{message}'"
|
|
56
|
-
)
|
|
57
|
-
increment = new_increment
|
|
58
|
-
|
|
59
|
-
if increment == MAJOR:
|
|
60
|
-
break
|
|
61
|
-
|
|
62
|
-
return cast("Increment", increment)
|
|
16
|
+
from commitizen.version_schemes import VersionProtocol
|
|
63
17
|
|
|
64
18
|
|
|
65
19
|
def update_version_in_files(
|
|
@@ -24,6 +24,7 @@ from commitizen.exceptions import (
|
|
|
24
24
|
)
|
|
25
25
|
from commitizen.providers import get_provider
|
|
26
26
|
from commitizen.tags import TagRules
|
|
27
|
+
from commitizen.version_increment import VersionIncrement
|
|
27
28
|
from commitizen.version_schemes import (
|
|
28
29
|
Increment,
|
|
29
30
|
InvalidVersion,
|
|
@@ -145,8 +146,8 @@ class Bump:
|
|
|
145
146
|
return bool(questionary.confirm("Is this the first tag created?").ask())
|
|
146
147
|
|
|
147
148
|
def _find_increment(self, commits: list[git.GitCommit]) -> Increment | None:
|
|
149
|
+
"""Determine the highest configured increment across candidate commits."""
|
|
148
150
|
# Update the bump map to ensure major version doesn't increment.
|
|
149
|
-
# self.cz.bump_map = defaults.bump_map_major_version_zero
|
|
150
151
|
bump_map = (
|
|
151
152
|
self.cz.bump_map_major_version_zero
|
|
152
153
|
if self.bump_settings["major_version_zero"]
|
|
@@ -158,7 +159,18 @@ class Bump:
|
|
|
158
159
|
raise NoPatternMapError(
|
|
159
160
|
f"'{self.config.settings['name']}' rule does not support bump"
|
|
160
161
|
)
|
|
161
|
-
|
|
162
|
+
|
|
163
|
+
commit_messages = (
|
|
164
|
+
commit.message for commit in self.cz.filter_commits_before_bump(commits)
|
|
165
|
+
)
|
|
166
|
+
increment = VersionIncrement.get_highest_by_messages(
|
|
167
|
+
commit_messages,
|
|
168
|
+
bump_pattern,
|
|
169
|
+
bump_map,
|
|
170
|
+
)
|
|
171
|
+
if increment == VersionIncrement.NONE:
|
|
172
|
+
return None
|
|
173
|
+
return cast("Increment", str(increment))
|
|
162
174
|
|
|
163
175
|
def _validate_arguments(self, current_version: VersionProtocol) -> None:
|
|
164
176
|
errors: list[str] = []
|
|
@@ -4,7 +4,7 @@ from typing import TypedDict
|
|
|
4
4
|
|
|
5
5
|
from packaging.version import InvalidVersion
|
|
6
6
|
|
|
7
|
-
from commitizen import
|
|
7
|
+
from commitizen import factory, git, out
|
|
8
8
|
from commitizen.__version__ import __version__
|
|
9
9
|
from commitizen.config import BaseConfig
|
|
10
10
|
from commitizen.exceptions import (
|
|
@@ -180,9 +180,20 @@ class Version:
|
|
|
180
180
|
raise NoPatternMapError(
|
|
181
181
|
f"'{self.config.settings['name']}' rule does not support bump"
|
|
182
182
|
)
|
|
183
|
-
|
|
184
|
-
commits,
|
|
183
|
+
next_increment = VersionIncrement.get_highest_by_messages(
|
|
184
|
+
(commit.message for commit in self.cz.filter_commits_before_bump(commits)),
|
|
185
|
+
bump_pattern,
|
|
186
|
+
bump_map,
|
|
185
187
|
)
|
|
188
|
+
increment: Increment | None
|
|
189
|
+
if next_increment == VersionIncrement.NONE:
|
|
190
|
+
increment = None
|
|
191
|
+
elif next_increment == VersionIncrement.PATCH:
|
|
192
|
+
increment = "PATCH"
|
|
193
|
+
elif next_increment == VersionIncrement.MINOR:
|
|
194
|
+
increment = "MINOR"
|
|
195
|
+
else:
|
|
196
|
+
increment = "MAJOR"
|
|
186
197
|
|
|
187
198
|
# TODO: Consider adding all the parameters `.bump` supports:
|
|
188
199
|
# prerelease, prerelease_offset,exact_increment, etc..
|
|
@@ -37,8 +37,8 @@ class ValidationResult(NamedTuple):
|
|
|
37
37
|
|
|
38
38
|
class BaseCommitizen(metaclass=ABCMeta):
|
|
39
39
|
bump_pattern: str | None = None
|
|
40
|
-
bump_map:
|
|
41
|
-
bump_map_major_version_zero:
|
|
40
|
+
bump_map: Mapping[str, str | None] | None = None
|
|
41
|
+
bump_map_major_version_zero: Mapping[str, str | None] | None = None
|
|
42
42
|
default_style_config: list[tuple[str, str]] = [
|
|
43
43
|
("qmark", "fg:#ff9d00 bold"),
|
|
44
44
|
("question", "bold"),
|
|
@@ -78,6 +78,52 @@ class BaseCommitizen(metaclass=ABCMeta):
|
|
|
78
78
|
if not self.config.settings.get("style"):
|
|
79
79
|
self.config.settings.update({"style": BaseCommitizen.default_style_config})
|
|
80
80
|
|
|
81
|
+
def filter_commits(self, commits: list[git.GitCommit]) -> list[git.GitCommit]:
|
|
82
|
+
"""Select commits shared by bump and changelog operations.
|
|
83
|
+
|
|
84
|
+
Custom rules can override this method when both operations should use the
|
|
85
|
+
same subset of commits.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
commits: The commits available to the current operation.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The commits that the rule considers relevant.
|
|
92
|
+
"""
|
|
93
|
+
return commits
|
|
94
|
+
|
|
95
|
+
def filter_commits_before_bump(
|
|
96
|
+
self, commits: list[git.GitCommit]
|
|
97
|
+
) -> list[git.GitCommit]:
|
|
98
|
+
"""Select commits before calculating a version increment.
|
|
99
|
+
|
|
100
|
+
This operation-specific hook delegates to `filter_commits` so custom rules
|
|
101
|
+
can share filtering by default or override only bump behavior.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
commits: The commits available for bump calculation.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
The commits that should contribute to the version increment.
|
|
108
|
+
"""
|
|
109
|
+
return self.filter_commits(commits)
|
|
110
|
+
|
|
111
|
+
def filter_commits_before_changelog(
|
|
112
|
+
self, commits: list[git.GitCommit]
|
|
113
|
+
) -> list[git.GitCommit]:
|
|
114
|
+
"""Select commits before generating a changelog.
|
|
115
|
+
|
|
116
|
+
This operation-specific hook delegates to `filter_commits` so custom rules
|
|
117
|
+
can share filtering by default or override only changelog behavior.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
commits: The commits available for changelog generation.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
The commits that should contribute to the changelog.
|
|
124
|
+
"""
|
|
125
|
+
return self.filter_commits(commits)
|
|
126
|
+
|
|
81
127
|
@abstractmethod
|
|
82
128
|
def questions(self) -> list[CzQuestion]:
|
|
83
129
|
"""Questions regarding the commit message."""
|
{commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/conventional_commits.py
RENAMED
|
@@ -8,6 +8,8 @@ from commitizen.cz.base import BaseCommitizen
|
|
|
8
8
|
from commitizen.cz.utils import multiple_line_breaker, required_validator
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Mapping
|
|
12
|
+
|
|
11
13
|
from commitizen.question import CzQuestion
|
|
12
14
|
|
|
13
15
|
__all__ = ["ConventionalCommitsCz"]
|
|
@@ -32,8 +34,10 @@ class ConventionalCommitsAnswers(TypedDict):
|
|
|
32
34
|
|
|
33
35
|
class ConventionalCommitsCz(BaseCommitizen):
|
|
34
36
|
bump_pattern = defaults.BUMP_PATTERN
|
|
35
|
-
bump_map = defaults.BUMP_MAP
|
|
36
|
-
bump_map_major_version_zero =
|
|
37
|
+
bump_map: Mapping[str, str | None] = defaults.BUMP_MAP
|
|
38
|
+
bump_map_major_version_zero: Mapping[str, str | None] = (
|
|
39
|
+
defaults.BUMP_MAP_MAJOR_VERSION_ZERO
|
|
40
|
+
)
|
|
37
41
|
commit_parser = r"^((?P<change_type>feat|fix|refactor|perf|BREAKING CHANGE)(?:\((?P<scope>[^()\r\n]*)\)|\()?(?P<breaking>!)?|\w+!):\s(?P<message>.*)?"
|
|
38
42
|
change_type_map = {
|
|
39
43
|
"feat": "Feat",
|
|
@@ -27,8 +27,8 @@ __all__ = ["CustomizeCommitsCz"]
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def _derive_major_version_zero(
|
|
30
|
-
bump_map: Mapping[str, str],
|
|
31
|
-
) -> OrderedDict[str, str]:
|
|
30
|
+
bump_map: Mapping[str, str | None],
|
|
31
|
+
) -> OrderedDict[str, str | None]:
|
|
32
32
|
"""Derive a ``bump_map_major_version_zero`` from a user-supplied
|
|
33
33
|
``bump_map`` by demoting any ``MAJOR`` rule to ``MINOR``.
|
|
34
34
|
|
|
@@ -45,8 +45,10 @@ def _derive_major_version_zero(
|
|
|
45
45
|
|
|
46
46
|
class CustomizeCommitsCz(BaseCommitizen):
|
|
47
47
|
bump_pattern = defaults.BUMP_PATTERN
|
|
48
|
-
bump_map = defaults.BUMP_MAP
|
|
49
|
-
bump_map_major_version_zero =
|
|
48
|
+
bump_map: Mapping[str, str | None] = defaults.BUMP_MAP
|
|
49
|
+
bump_map_major_version_zero: Mapping[str, str | None] = (
|
|
50
|
+
defaults.BUMP_MAP_MAJOR_VERSION_ZERO
|
|
51
|
+
)
|
|
50
52
|
change_type_order = defaults.CHANGE_TYPE_ORDER
|
|
51
53
|
|
|
52
54
|
def __init__(self, config: BaseConfig) -> None:
|
|
@@ -13,8 +13,8 @@ if TYPE_CHECKING:
|
|
|
13
13
|
|
|
14
14
|
class CzSettings(TypedDict, total=False):
|
|
15
15
|
bump_pattern: str
|
|
16
|
-
bump_map: OrderedDict[str, str]
|
|
17
|
-
bump_map_major_version_zero: OrderedDict[str, str]
|
|
16
|
+
bump_map: OrderedDict[str, str | None]
|
|
17
|
+
bump_map_major_version_zero: OrderedDict[str, str | None]
|
|
18
18
|
change_type_order: list[str]
|
|
19
19
|
|
|
20
20
|
questions: Iterable[CzQuestion]
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""Helpers for comparing and deriving semantic-version increments.
|
|
2
|
+
|
|
3
|
+
This module centralizes the conversion between external increment labels and the
|
|
4
|
+
ordered enum used internally by bump-related commands. The distinction matters
|
|
5
|
+
because some callers intentionally coerce unknown values to ``NONE`` while
|
|
6
|
+
matched ``bump_map`` outputs must preserve the historical fail-fast behavior for
|
|
7
|
+
invalid custom rule values.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
from enum import IntEnum
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from collections.abc import Iterable, Mapping
|
|
18
|
+
|
|
19
|
+
RegexPattern = str | re.Pattern[str]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class VersionIncrement(IntEnum):
|
|
23
|
+
"""Semantic versioning bump increments.
|
|
24
|
+
|
|
25
|
+
IntEnum keeps a total order compatible with NONE < PATCH < MINOR < MAJOR
|
|
26
|
+
for comparisons across the codebase.
|
|
27
|
+
|
|
28
|
+
- NONE: no bump (docs-only / style commits, etc.)
|
|
29
|
+
- PATCH: backwards-compatible bug fixes
|
|
30
|
+
- MINOR: backwards-compatible features
|
|
31
|
+
- MAJOR: incompatible API changes
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
```python
|
|
35
|
+
max([VersionIncrement.PATCH, VersionIncrement.MINOR])
|
|
36
|
+
# VersionIncrement.MINOR
|
|
37
|
+
```
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
NONE = 0
|
|
41
|
+
PATCH = 1
|
|
42
|
+
MINOR = 2
|
|
43
|
+
MAJOR = 3
|
|
44
|
+
|
|
45
|
+
def __str__(self) -> str:
|
|
46
|
+
"""Return the legacy string representation used by existing callers."""
|
|
47
|
+
return self.name
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def from_value(cls, value: object) -> VersionIncrement:
|
|
51
|
+
"""Convert external increment input into a known increment.
|
|
52
|
+
|
|
53
|
+
This lenient path is used for inputs such as CLI arguments where an
|
|
54
|
+
unknown string should behave like "no increment" instead of raising.
|
|
55
|
+
Matched ``bump_map`` values are validated separately so custom rules keep
|
|
56
|
+
their historical fail-fast behavior.
|
|
57
|
+
"""
|
|
58
|
+
if not isinstance(value, str):
|
|
59
|
+
return VersionIncrement.NONE
|
|
60
|
+
try:
|
|
61
|
+
return cls[value]
|
|
62
|
+
except KeyError:
|
|
63
|
+
return VersionIncrement.NONE
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def _compile_pattern(cls, regex: RegexPattern) -> re.Pattern[str]:
|
|
67
|
+
"""Normalize a bump-pattern input into a compiled regular expression."""
|
|
68
|
+
if isinstance(regex, re.Pattern):
|
|
69
|
+
return regex
|
|
70
|
+
return re.compile(regex)
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def _from_bump_map_value(cls, value: object) -> VersionIncrement:
|
|
74
|
+
"""Resolve a configured bump-map value or reject invalid rule output.
|
|
75
|
+
|
|
76
|
+
This preserves the historical behavior where a matched custom bump-map
|
|
77
|
+
entry with an unsupported increment fails immediately instead of being
|
|
78
|
+
treated as a no-op.
|
|
79
|
+
"""
|
|
80
|
+
if value is None:
|
|
81
|
+
return cls.NONE
|
|
82
|
+
if value == "PATCH":
|
|
83
|
+
return cls.PATCH
|
|
84
|
+
if value == "MINOR":
|
|
85
|
+
return cls.MINOR
|
|
86
|
+
if value == "MAJOR":
|
|
87
|
+
return cls.MAJOR
|
|
88
|
+
raise ValueError(f"Invalid bump increment: {value!r}")
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def from_match(
|
|
92
|
+
cls, matched_text: str, increments_map: Mapping[str, object]
|
|
93
|
+
) -> VersionIncrement:
|
|
94
|
+
"""Resolve one extracted bump token against a configured bump map.
|
|
95
|
+
|
|
96
|
+
The first regular-expression key that matches wins, preserving the
|
|
97
|
+
current user-visible behavior of ``bump_map`` ordering.
|
|
98
|
+
"""
|
|
99
|
+
for match_pattern, increment in increments_map.items():
|
|
100
|
+
if re.match(match_pattern, matched_text):
|
|
101
|
+
return cls._from_bump_map_value(increment)
|
|
102
|
+
return cls.NONE
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def from_message(
|
|
106
|
+
cls, message: str, regex: RegexPattern, increments_map: Mapping[str, object]
|
|
107
|
+
) -> VersionIncrement:
|
|
108
|
+
"""Compute the highest increment contributed by one commit message.
|
|
109
|
+
|
|
110
|
+
Commitizen historically evaluates each line of the full commit message
|
|
111
|
+
against ``bump_pattern`` and then keeps the highest resulting bump.
|
|
112
|
+
This method preserves that behavior while returning a comparable enum.
|
|
113
|
+
"""
|
|
114
|
+
select_pattern = cls._compile_pattern(regex)
|
|
115
|
+
increment = cls.NONE
|
|
116
|
+
|
|
117
|
+
for line in message.split("\n"):
|
|
118
|
+
result = select_pattern.search(line)
|
|
119
|
+
if not result:
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
increment = max(
|
|
123
|
+
increment,
|
|
124
|
+
cls.from_match(result.group(1), increments_map),
|
|
125
|
+
)
|
|
126
|
+
if increment == cls.MAJOR:
|
|
127
|
+
return increment
|
|
128
|
+
|
|
129
|
+
return increment
|
|
130
|
+
|
|
131
|
+
@classmethod
|
|
132
|
+
def get_highest_by_messages(
|
|
133
|
+
cls,
|
|
134
|
+
messages: Iterable[str],
|
|
135
|
+
regex: RegexPattern,
|
|
136
|
+
increments_map: Mapping[str, object],
|
|
137
|
+
) -> VersionIncrement:
|
|
138
|
+
"""Compute the highest increment across many commit messages.
|
|
139
|
+
|
|
140
|
+
An empty iterable yields ``NONE`` so callers can preserve the existing
|
|
141
|
+
"no increment" behavior explicitly instead of relying on exceptions from
|
|
142
|
+
``max()``.
|
|
143
|
+
"""
|
|
144
|
+
select_pattern = cls._compile_pattern(regex)
|
|
145
|
+
return max(
|
|
146
|
+
(
|
|
147
|
+
cls.from_message(message, select_pattern, increments_map)
|
|
148
|
+
for message in messages
|
|
149
|
+
),
|
|
150
|
+
default=cls.NONE,
|
|
151
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "commitizen"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.19.1"
|
|
4
4
|
description = "Python commitizen client tool"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
license-files = ["LICENSE"]
|
|
@@ -153,7 +153,6 @@ version_provider = "uv"
|
|
|
153
153
|
version_scheme = "pep440"
|
|
154
154
|
annotated_tag = true
|
|
155
155
|
update_changelog_on_bump = true
|
|
156
|
-
changelog_incremental = true
|
|
157
156
|
|
|
158
157
|
[tool.uv.build-backend]
|
|
159
158
|
module-name = "commitizen"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "commitizen"
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.19.1"
|
|
4
4
|
description = "Python commitizen client tool"
|
|
5
5
|
authors = [{ name = "Santiago Fraire", email = "santiwilly@gmail.com" }]
|
|
6
6
|
maintainers = [
|
|
@@ -147,7 +147,6 @@ version_provider = "uv"
|
|
|
147
147
|
version_scheme = "pep440"
|
|
148
148
|
annotated_tag = true
|
|
149
149
|
update_changelog_on_bump = true
|
|
150
|
-
changelog_incremental = true
|
|
151
150
|
|
|
152
151
|
[tool.uv.build-backend]
|
|
153
152
|
module-name = "commitizen"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "4.18.1"
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from enum import IntEnum
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class VersionIncrement(IntEnum):
|
|
7
|
-
"""Semantic versioning bump increments.
|
|
8
|
-
|
|
9
|
-
IntEnum keeps a total order compatible with NONE < PATCH < MINOR < MAJOR
|
|
10
|
-
for comparisons across the codebase.
|
|
11
|
-
|
|
12
|
-
- NONE: no bump (docs-only / style commits, etc.)
|
|
13
|
-
- PATCH: backwards-compatible bug fixes
|
|
14
|
-
- MINOR: backwards-compatible features
|
|
15
|
-
- MAJOR: incompatible API changes
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
NONE = 0
|
|
19
|
-
PATCH = 1
|
|
20
|
-
MINOR = 2
|
|
21
|
-
MAJOR = 3
|
|
22
|
-
|
|
23
|
-
def __str__(self) -> str:
|
|
24
|
-
return self.name
|
|
25
|
-
|
|
26
|
-
@classmethod
|
|
27
|
-
def from_value(cls, value: object) -> VersionIncrement:
|
|
28
|
-
if not isinstance(value, str):
|
|
29
|
-
return VersionIncrement.NONE
|
|
30
|
-
try:
|
|
31
|
-
return cls[value]
|
|
32
|
-
except KeyError:
|
|
33
|
-
return VersionIncrement.NONE
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|