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.
Files changed (76) hide show
  1. {commitizen-4.18.1 → commitizen-4.19.1}/PKG-INFO +1 -1
  2. commitizen-4.19.1/commitizen/__version__.py +1 -0
  3. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/bump.py +4 -50
  4. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/bump.py +14 -2
  5. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/changelog.py +1 -0
  6. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/version.py +14 -3
  7. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/base.py +48 -2
  8. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/conventional_commits.py +6 -2
  9. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/customize.py +6 -4
  10. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/defaults.py +2 -2
  11. commitizen-4.19.1/commitizen/version_increment.py +151 -0
  12. {commitizen-4.18.1 → commitizen-4.19.1}/pyproject.toml +1 -2
  13. {commitizen-4.18.1 → commitizen-4.19.1}/pyproject.toml.orig +1 -2
  14. commitizen-4.18.1/commitizen/__version__.py +0 -1
  15. commitizen-4.18.1/commitizen/version_increment.py +0 -33
  16. {commitizen-4.18.1 → commitizen-4.19.1}/LICENSE +0 -0
  17. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/__init__.py +0 -0
  18. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/__main__.py +0 -0
  19. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog.py +0 -0
  20. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/__init__.py +0 -0
  21. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/asciidoc.py +0 -0
  22. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/base.py +0 -0
  23. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/markdown.py +0 -0
  24. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/restructuredtext.py +0 -0
  25. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/changelog_formats/textile.py +0 -0
  26. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cli.py +0 -0
  27. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cmd.py +0 -0
  28. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/__init__.py +0 -0
  29. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/check.py +0 -0
  30. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/commit.py +0 -0
  31. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/example.py +0 -0
  32. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/info.py +0 -0
  33. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/init.py +0 -0
  34. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/list_cz.py +0 -0
  35. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/commands/schema.py +0 -0
  36. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/__init__.py +0 -0
  37. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/base_config.py +0 -0
  38. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/factory.py +0 -0
  39. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/json_config.py +0 -0
  40. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/toml_config.py +0 -0
  41. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/config/yaml_config.py +0 -0
  42. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/__init__.py +0 -0
  43. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/__init__.py +0 -0
  44. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/conventional_commits/conventional_commits_info.txt +0 -0
  45. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/__init__.py +0 -0
  46. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/customize/customize_info.txt +0 -0
  47. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/exceptions.py +0 -0
  48. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/__init__.py +0 -0
  49. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/jira.py +0 -0
  50. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/jira/jira_info.txt +0 -0
  51. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/cz/utils.py +0 -0
  52. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/exceptions.py +0 -0
  53. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/factory.py +0 -0
  54. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/git.py +0 -0
  55. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/hooks.py +0 -0
  56. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/out.py +0 -0
  57. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/project_info.py +0 -0
  58. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/__init__.py +0 -0
  59. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/base_provider.py +0 -0
  60. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/cargo_provider.py +0 -0
  61. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/commitizen_provider.py +0 -0
  62. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/composer_provider.py +0 -0
  63. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/npm_provider.py +0 -0
  64. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/pep621_provider.py +0 -0
  65. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/poetry_provider.py +0 -0
  66. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/scm_provider.py +0 -0
  67. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/providers/uv_provider.py +0 -0
  68. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/py.typed +0 -0
  69. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/question.py +0 -0
  70. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/tags.py +0 -0
  71. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.adoc.j2 +0 -0
  72. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.md.j2 +0 -0
  73. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.rst.j2 +0 -0
  74. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/templates/CHANGELOG.textile.j2 +0 -0
  75. {commitizen-4.18.1 → commitizen-4.19.1}/commitizen/version_schemes.py +0 -0
  76. {commitizen-4.18.1 → commitizen-4.19.1}/docs/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commitizen
3
- Version: 4.18.1
3
+ Version: 4.19.1
4
4
  Summary: Python commitizen client tool
5
5
  Keywords: commitizen,conventional,commits,git
6
6
  Author: Santiago Fraire
@@ -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, cast
7
+ from typing import TYPE_CHECKING
10
8
 
11
- from commitizen.defaults import BUMP_MESSAGE, MAJOR, MINOR, PATCH
9
+ from commitizen.defaults import BUMP_MESSAGE
12
10
  from commitizen.exceptions import CurrentVersionNotFoundError
13
- from commitizen.git import GitCommit, smart_open
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 Increment, VersionProtocol
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
- return bump.find_increment(commits, regex=bump_pattern, increments_map=bump_map)
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] = []
@@ -265,6 +265,7 @@ class Changelog:
265
265
  ):
266
266
  raise NoCommitsFoundError("No commits found")
267
267
 
268
+ commits = self.cz.filter_commits_before_changelog(commits)
268
269
  tree = changelog.generate_tree_from_commits(
269
270
  commits,
270
271
  tags,
@@ -4,7 +4,7 @@ from typing import TypedDict
4
4
 
5
5
  from packaging.version import InvalidVersion
6
6
 
7
- from commitizen import bump, factory, git, out
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
- increment = bump.find_increment(
184
- commits, regex=bump_pattern, increments_map=bump_map
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: dict[str, str] | None = None
41
- bump_map_major_version_zero: dict[str, str] | None = None
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."""
@@ -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 = defaults.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 = defaults.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.18.1"
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.18.1"
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