commitizen 4.19.0__tar.gz → 4.19.2__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.19.0 → commitizen-4.19.2}/PKG-INFO +1 -1
- commitizen-4.19.2/commitizen/__version__.py +1 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/bump.py +4 -50
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/bump.py +13 -5
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/version.py +14 -5
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/base.py +2 -2
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/conventional_commits/conventional_commits.py +6 -2
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/customize/customize.py +6 -4
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/defaults.py +2 -2
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/tags.py +5 -2
- commitizen-4.19.2/commitizen/version_increment.py +151 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/pyproject.toml +1 -1
- {commitizen-4.19.0 → commitizen-4.19.2}/pyproject.toml.orig +1 -1
- commitizen-4.19.0/commitizen/__version__.py +0 -1
- commitizen-4.19.0/commitizen/version_increment.py +0 -33
- {commitizen-4.19.0 → commitizen-4.19.2}/LICENSE +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/__main__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/asciidoc.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/base.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/markdown.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/restructuredtext.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/changelog_formats/textile.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cli.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cmd.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/changelog.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/check.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/commit.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/example.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/info.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/init.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/list_cz.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/commands/schema.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/base_config.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/factory.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/json_config.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/toml_config.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/config/yaml_config.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/conventional_commits/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/conventional_commits/conventional_commits_info.txt +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/customize/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/customize/customize_info.txt +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/exceptions.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/jira/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/jira/jira.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/jira/jira_info.txt +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/cz/utils.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/exceptions.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/factory.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/git.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/hooks.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/out.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/project_info.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/__init__.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/base_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/cargo_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/commitizen_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/composer_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/npm_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/pep621_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/poetry_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/scm_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/providers/uv_provider.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/py.typed +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/question.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/templates/CHANGELOG.adoc.j2 +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/templates/CHANGELOG.md.j2 +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/templates/CHANGELOG.rst.j2 +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/templates/CHANGELOG.textile.j2 +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/commitizen/version_schemes.py +0 -0
- {commitizen-4.19.0 → commitizen-4.19.2}/docs/README.md +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "4.19.2"
|
|
@@ -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,11 +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
|
-
|
|
164
|
-
|
|
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,
|
|
165
170
|
)
|
|
171
|
+
if increment == VersionIncrement.NONE:
|
|
172
|
+
return None
|
|
173
|
+
return cast("Increment", str(increment))
|
|
166
174
|
|
|
167
175
|
def _validate_arguments(self, current_version: VersionProtocol) -> None:
|
|
168
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,11 +180,20 @@ class Version:
|
|
|
180
180
|
raise NoPatternMapError(
|
|
181
181
|
f"'{self.config.settings['name']}' rule does not support bump"
|
|
182
182
|
)
|
|
183
|
-
|
|
184
|
-
self.cz.filter_commits_before_bump(commits),
|
|
185
|
-
|
|
186
|
-
|
|
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,
|
|
187
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"
|
|
188
197
|
|
|
189
198
|
# TODO: Consider adding all the parameters `.bump` supports:
|
|
190
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"),
|
{commitizen-4.19.0 → commitizen-4.19.2}/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]
|
|
@@ -127,15 +127,18 @@ class TagRules:
|
|
|
127
127
|
if `warn` is `True`, it will print a warning message if the tag is not a version tag.
|
|
128
128
|
"""
|
|
129
129
|
tag = tag.name if isinstance(tag, GitTag) else tag
|
|
130
|
+
if self.is_ignored_tag(tag):
|
|
131
|
+
return False
|
|
132
|
+
|
|
130
133
|
is_legit = any(regex.fullmatch(tag) for regex in self.version_regexes)
|
|
131
|
-
if warn and not is_legit
|
|
134
|
+
if warn and not is_legit:
|
|
132
135
|
out.warn(self._version_tag_error(tag))
|
|
133
136
|
return is_legit
|
|
134
137
|
|
|
135
138
|
def is_ignored_tag(self, tag: str | GitTag) -> bool:
|
|
136
139
|
"""True if a given tag can be ignored"""
|
|
137
140
|
tag = tag.name if isinstance(tag, GitTag) else tag
|
|
138
|
-
return any(regex.
|
|
141
|
+
return any(regex.fullmatch(tag) for regex in self.ignored_regexes)
|
|
139
142
|
|
|
140
143
|
def get_version_tags(
|
|
141
144
|
self, tags: Iterable[GitTag], warn: bool = False
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
__version__ = "4.19.0"
|
|
@@ -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
|