Skip to content

Commit 36de6ee

Browse files
authored
Merge branch 'v3' into version_provider
2 parents 047f2d1 + 7a8c2d8 commit 36de6ee

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3164
-190
lines changed

.github/dependabot.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
updates:
3+
-
4+
# Maintain dependencies for GitHub Actions
5+
package-ecosystem: github-actions
6+
directory: /
7+
schedule:
8+
interval: daily
9+
labels:
10+
- dependencies
11+
commit-message:
12+
prefix: "ci(actions)"
13+
include: "scope"
14+
-
15+
# Maintain python dependencies
16+
package-ecosystem: pip
17+
directory: /
18+
schedule:
19+
interval: daily
20+
labels:
21+
- dependencies
22+
commit-message:
23+
prefix: "build(poetry)"
24+
include: "scope"

.github/workflows/pythonpackage.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jobs:
66
python-check:
77
strategy:
88
matrix:
9-
python-version: ["3.7", "3.8", "3.9", "3.10"]
9+
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
1010
platform: [ubuntu-20.04, macos-latest, windows-latest]
1111
runs-on: ${{ matrix.platform }}
1212
steps:
@@ -30,7 +30,7 @@ jobs:
3030
shell: bash
3131
- name: Upload coverage to Codecov
3232
if: runner.os == 'Linux'
33-
uses: codecov/codecov-action@v1.0.3
33+
uses: codecov/codecov-action@v3
3434
with:
3535
token: ${{secrets.CODECOV_TOKEN}}
3636
file: ./coverage.xml

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,5 @@ venv.bak/
108108
.vscode/
109109
*.bak
110110

111-
# build
112-
poetry.lock
113-
114111
# macOSX
115112
.DS_Store

commitizen/changelog.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from typing import Callable, Dict, Iterable, List, Optional, Tuple, Type
3535

3636
from jinja2 import Environment, PackageLoader
37+
from packaging.version import InvalidVersion, Version
3738

3839
from commitizen import defaults
3940
from commitizen.bump import normalize_tag
@@ -51,6 +52,31 @@ def get_commit_tag(commit: GitCommit, tags: List[GitTag]) -> Optional[GitTag]:
5152
return next((tag for tag in tags if tag.rev == commit.rev), None)
5253

5354

55+
def get_version(tag: GitTag) -> Optional[Version]:
56+
version = None
57+
try:
58+
version = Version(tag.name)
59+
except InvalidVersion:
60+
pass
61+
return version
62+
63+
64+
def tag_included_in_changelog(
65+
tag: GitTag, used_tags: List, merge_prerelease: bool
66+
) -> bool:
67+
if tag in used_tags:
68+
return False
69+
70+
version = get_version(tag)
71+
if version is None:
72+
return False
73+
74+
if merge_prerelease and version.is_prerelease:
75+
return False
76+
77+
return True
78+
79+
5480
def generate_tree_from_commits(
5581
commits: List[GitCommit],
5682
tags: List[GitTag],
@@ -59,6 +85,7 @@ def generate_tree_from_commits(
5985
unreleased_version: Optional[str] = None,
6086
change_type_map: Optional[Dict[str, str]] = None,
6187
changelog_message_builder_hook: Optional[Callable] = None,
88+
merge_prerelease: bool = False,
6289
) -> Iterable[Dict]:
6390
pat = re.compile(changelog_pattern)
6491
map_pat = re.compile(commit_parser, re.MULTILINE)
@@ -81,15 +108,15 @@ def generate_tree_from_commits(
81108
for commit in commits:
82109
commit_tag = get_commit_tag(commit, tags)
83110

84-
if commit_tag is not None and commit_tag not in used_tags:
111+
if commit_tag is not None and tag_included_in_changelog(
112+
commit_tag, used_tags, merge_prerelease
113+
):
85114
used_tags.append(commit_tag)
86115
yield {
87116
"version": current_tag_name,
88117
"date": current_tag_date,
89118
"changes": changes,
90119
}
91-
# TODO: Check if tag matches the version pattern, otherwise skip it.
92-
# This in order to prevent tags that are not versions.
93120
current_tag_name = commit_tag.name
94121
current_tag_date = commit_tag.date
95122
changes = defaultdict(list)

commitizen/cli.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
import sys
44
from functools import partial
5+
from types import TracebackType
56
from typing import List
67

78
import argcomplete
@@ -253,10 +254,19 @@
253254
"name": "--start-rev",
254255
"default": None,
255256
"help": (
256-
"start rev of the changelog."
257+
"start rev of the changelog. "
257258
"If not set, it will generate changelog from the start"
258259
),
259260
},
261+
{
262+
"name": "--merge-prerelease",
263+
"action": "store_true",
264+
"default": False,
265+
"help": (
266+
"collect all changes from prereleases into next non-prerelease. "
267+
"If not set, it will include prereleases in the changelog"
268+
),
269+
},
260270
],
261271
},
262272
{
@@ -336,21 +346,22 @@
336346

337347

338348
def commitizen_excepthook(
339-
type, value, tracekback, debug=False, no_raise: List[int] = None
349+
type, value, traceback, debug=False, no_raise: List[int] = None
340350
):
351+
traceback = traceback if isinstance(traceback, TracebackType) else None
341352
if not no_raise:
342353
no_raise = []
343354
if isinstance(value, CommitizenException):
344355
if value.message:
345356
value.output_method(value.message)
346357
if debug:
347-
original_excepthook(type, value, tracekback)
358+
original_excepthook(type, value, traceback)
348359
exit_code = value.exit_code
349360
if exit_code in no_raise:
350361
exit_code = 0
351362
sys.exit(exit_code)
352363
else:
353-
original_excepthook(type, value, tracekback)
364+
original_excepthook(type, value, traceback)
354365

355366

356367
commitizen_debug_excepthook = partial(commitizen_excepthook, debug=True)

commitizen/commands/bump.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
NotAllowed,
2222
NoVersionSpecifiedError,
2323
)
24+
from commitizen.providers import get_provider
2425

2526
logger = getLogger("commitizen")
2627

@@ -98,14 +99,14 @@ def find_increment(self, commits: List[git.GitCommit]) -> Optional[str]:
9899

99100
def __call__(self): # noqa: C901
100101
"""Steps executed to bump."""
102+
provider = get_provider(self.config)
103+
current_version: str = provider.get_version()
104+
101105
try:
102-
current_version_instance: Version = Version(self.bump_settings["version"])
106+
current_version_instance: Version = Version(current_version)
103107
except TypeError:
104108
raise NoVersionSpecifiedError()
105109

106-
# Initialize values from sources (conf)
107-
current_version: str = self.config.settings["version"]
108-
109110
tag_format: str = self.bump_settings["tag_format"]
110111
bump_commit_message: str = self.bump_settings["bump_message"]
111112
version_files: List[str] = self.bump_settings["version_files"]
@@ -291,7 +292,7 @@ def __call__(self): # noqa: C901
291292
check_consistency=self.check_consistency,
292293
)
293294

294-
self.config.set_key("version", str(new_version))
295+
provider.set_version(str(new_version))
295296

296297
if self.pre_bump_hooks:
297298
hooks.run(

commitizen/commands/changelog.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ def __init__(self, config: BaseConfig, args):
4949
self.tag_format = args.get("tag_format") or self.config.settings.get(
5050
"tag_format"
5151
)
52+
self.merge_prerelease = args.get(
53+
"merge_prerelease"
54+
) or self.config.settings.get("changelog_merge_prerelease")
5255

5356
version_type = self.config.settings.get("version_type")
5457
self.version_type = version_type and version_types.VERSION_TYPES[version_type]
@@ -113,6 +116,7 @@ def __call__(self):
113116
changelog_message_builder_hook: Optional[
114117
Callable
115118
] = self.cz.changelog_message_builder_hook
119+
merge_prerelease = self.merge_prerelease
116120

117121
if not changelog_pattern or not commit_parser:
118122
raise NoPatternMapError(
@@ -150,9 +154,7 @@ def __call__(self):
150154
version_type_cls=self.version_type,
151155
)
152156

153-
commits = git.get_commits(
154-
start=start_rev, end=end_rev, args="--author-date-order"
155-
)
157+
commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order")
156158
if not commits:
157159
raise NoCommitsFoundError("No commits found")
158160

@@ -164,6 +166,7 @@ def __call__(self):
164166
unreleased_version,
165167
change_type_map=change_type_map,
166168
changelog_message_builder_hook=changelog_message_builder_hook,
169+
merge_prerelease=merge_prerelease,
167170
)
168171
if self.change_type_order:
169172
tree = changelog.order_changelog_tree(tree, self.change_type_order)

commitizen/commands/version.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from commitizen import out
55
from commitizen.__version__ import __version__
66
from commitizen.config import BaseConfig
7+
from commitizen.providers import get_provider
78

89

910
class Version:
@@ -21,14 +22,14 @@ def __call__(self):
2122
out.write(f"Python Version: {self.python_version}")
2223
out.write(f"Operating System: {self.operating_system}")
2324
elif self.parameter.get("project"):
24-
version = self.config.settings["version"]
25+
version = get_provider(self.config).get_version()
2526
if version:
2627
out.write(f"{version}")
2728
else:
2829
out.error("No project information in this project.")
2930
elif self.parameter.get("verbose"):
3031
out.write(f"Installed Commitizen Version: {__version__}")
31-
version = self.config.settings["version"]
32+
version = get_provider(self.config).get_version()
3233
if version:
3334
out.write(f"Project Version: {version}")
3435
else:

commitizen/cz/__init__.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
from __future__ import annotations
2+
13
import importlib
24
import pkgutil
35
import warnings
4-
from typing import Dict, Iterable, Type
6+
from typing import Iterable, Optional
7+
8+
import importlib_metadata as metadata
59

610
from commitizen.cz.base import BaseCommitizen
7-
from commitizen.cz.conventional_commits import ConventionalCommitsCz
8-
from commitizen.cz.customize import CustomizeCommitsCz
9-
from commitizen.cz.jira import JiraSmartCz
1011

1112

12-
def discover_plugins(path: Iterable[str] = None) -> Dict[str, Type[BaseCommitizen]]:
13+
def discover_plugins(
14+
path: Optional[Iterable[str]] = None,
15+
) -> dict[str, type[BaseCommitizen]]:
1316
"""Discover commitizen plugins on the path
1417
1518
Args:
@@ -19,21 +22,19 @@ def discover_plugins(path: Iterable[str] = None) -> Dict[str, Type[BaseCommitize
1922
Returns:
2023
Dict[str, Type[BaseCommitizen]]: Registry with found plugins
2124
"""
22-
plugins = {}
23-
for _finder, name, _ispkg in pkgutil.iter_modules(path):
24-
try:
25-
if name.startswith("cz_"):
26-
plugins[name] = importlib.import_module(name).discover_this
27-
except AttributeError as e:
28-
warnings.warn(UserWarning(e.args[0]))
29-
continue
30-
return plugins
31-
32-
33-
registry: Dict[str, Type[BaseCommitizen]] = {
34-
"cz_conventional_commits": ConventionalCommitsCz,
35-
"cz_jira": JiraSmartCz,
36-
"cz_customize": CustomizeCommitsCz,
37-
}
38-
39-
registry.update(discover_plugins())
25+
for _, name, _ in pkgutil.iter_modules(path):
26+
if name.startswith("cz_"):
27+
mod = importlib.import_module(name)
28+
if hasattr(mod, "discover_this"):
29+
warnings.warn(
30+
UserWarning(
31+
f"Legacy plugin '{name}' has been ignored: please expose it the 'commitizen.plugin' entrypoint"
32+
)
33+
)
34+
35+
return {
36+
ep.name: ep.load() for ep in metadata.entry_points(group="commitizen.plugin")
37+
}
38+
39+
40+
registry: dict[str, type[BaseCommitizen]] = discover_plugins()

commitizen/defaults.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ class Settings(TypedDict, total=False):
2929
name: str
3030
version: Optional[str]
3131
version_files: List[str]
32+
version_provider: Optional[str]
3233
tag_format: Optional[str]
3334
bump_message: Optional[str]
3435
allow_abort: bool
3536
changelog_file: str
3637
changelog_incremental: bool
3738
changelog_start_rev: Optional[str]
39+
changelog_merge_prerelease: bool
3840
update_changelog_on_bump: bool
3941
use_shortcuts: bool
4042
style: Optional[List[Tuple[str, str]]]
@@ -60,12 +62,14 @@ class Settings(TypedDict, total=False):
6062
"name": "cz_conventional_commits",
6163
"version": None,
6264
"version_files": [],
65+
"version_provider": "commitizen",
6366
"tag_format": None, # example v$version
6467
"bump_message": None, # bumped v$current_version to $new_version
6568
"allow_abort": False,
6669
"changelog_file": "CHANGELOG.md",
6770
"changelog_incremental": False,
6871
"changelog_start_rev": None,
72+
"changelog_merge_prerelease": False,
6973
"update_changelog_on_bump": False,
7074
"use_shortcuts": False,
7175
"major_version_zero": False,

commitizen/exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ExitCode(enum.IntEnum):
3131
INVALID_MANUAL_VERSION = 24
3232
INIT_FAILED = 25
3333
RUN_HOOK_FAILED = 26
34+
VERSION_PROVIDER_UNKNOWN = 27
3435

3536

3637
class CommitizenException(Exception):
@@ -173,3 +174,7 @@ class InitFailedError(CommitizenException):
173174

174175
class RunHookError(CommitizenException):
175176
exit_code = ExitCode.RUN_HOOK_FAILED
177+
178+
179+
class VersionProviderUnknown(CommitizenException):
180+
exit_code = ExitCode.VERSION_PROVIDER_UNKNOWN

0 commit comments

Comments
 (0)