Skip to content

Commit 4013f8a

Browse files
authored
Merge pull request #715 from commitizen-tools/v3
Release v3
2 parents 378a428 + 1a1e73b commit 4013f8a

File tree

65 files changed

+4528
-465
lines changed

Some content is hidden

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

65 files changed

+4528
-465
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/bumpversion.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,11 @@ jobs:
2020
uses: commitizen-tools/commitizen-action@master
2121
with:
2222
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
23+
changelog_increment_filename: body.md
24+
- name: Release
25+
uses: softprops/action-gh-release@v1
26+
with:
27+
body_path: "body.md"
28+
tag_name: ${{ env.REVISION }}
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ venv.bak/
108108
.vscode/
109109
*.bak
110110

111-
# build
112-
poetry.lock
113-
114111
# macOSX
115112
.DS_Store
113+
114+
# ruff
115+
.ruff_cache

commitizen/bump.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
import os
22
import re
3+
import sys
4+
import typing
35
from collections import OrderedDict
46
from itertools import zip_longest
57
from string import Template
6-
from typing import List, Optional, Tuple, Union
8+
from typing import List, Optional, Tuple, Type, Union
79

810
from packaging.version import Version
911

1012
from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message
1113
from commitizen.exceptions import CurrentVersionNotFoundError
1214
from commitizen.git import GitCommit, smart_open
1315

16+
if sys.version_info >= (3, 8):
17+
from commitizen.version_types import VersionProtocol
18+
else:
19+
# workaround mypy issue for 3.7 python
20+
VersionProtocol = typing.Any
21+
1422

1523
def find_increment(
1624
commits: List[GitCommit], regex: str, increments_map: Union[dict, OrderedDict]
@@ -120,7 +128,8 @@ def generate_version(
120128
prerelease_offset: int = 0,
121129
devrelease: Optional[int] = None,
122130
is_local_version: bool = False,
123-
) -> Version:
131+
version_type_cls: Optional[Type[VersionProtocol]] = None,
132+
) -> VersionProtocol:
124133
"""Based on the given increment a proper semver will be generated.
125134
126135
For now the rules and versioning scheme is based on
@@ -132,15 +141,17 @@ def generate_version(
132141
MINOR 1.0.0 -> 1.1.0
133142
MAJOR 1.0.0 -> 2.0.0
134143
"""
144+
if version_type_cls is None:
145+
version_type_cls = Version
135146
if is_local_version:
136-
version = Version(current_version)
147+
version = version_type_cls(current_version)
137148
dev_version = devrelease_generator(devrelease=devrelease)
138149
pre_version = prerelease_generator(
139150
str(version.local), prerelease=prerelease, offset=prerelease_offset
140151
)
141152
semver = semver_generator(str(version.local), increment=increment)
142153

143-
return Version(f"{version.public}+{semver}{pre_version}{dev_version}")
154+
return version_type_cls(f"{version.public}+{semver}{pre_version}{dev_version}")
144155
else:
145156
dev_version = devrelease_generator(devrelease=devrelease)
146157
pre_version = prerelease_generator(
@@ -149,7 +160,7 @@ def generate_version(
149160
semver = semver_generator(current_version, increment=increment)
150161

151162
# TODO: post version
152-
return Version(f"{semver}{pre_version}{dev_version}")
163+
return version_type_cls(f"{semver}{pre_version}{dev_version}")
153164

154165

155166
def update_version_in_files(
@@ -208,7 +219,9 @@ def _version_to_regex(version: str) -> str:
208219

209220

210221
def normalize_tag(
211-
version: Union[Version, str], tag_format: Optional[str] = None
222+
version: Union[VersionProtocol, str],
223+
tag_format: Optional[str] = None,
224+
version_type_cls: Optional[Type[VersionProtocol]] = None,
212225
) -> str:
213226
"""The tag and the software version might be different.
214227
@@ -221,8 +234,10 @@ def normalize_tag(
221234
| ver1.0.0 | 1.0.0 |
222235
| ver1.0.0.a0 | 1.0.0a0 |
223236
"""
237+
if version_type_cls is None:
238+
version_type_cls = Version
224239
if isinstance(version, str):
225-
version = Version(version)
240+
version = version_type_cls(version)
226241

227242
if not tag_format:
228243
return str(version)

commitizen/changelog.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,56 @@
2727

2828
import os
2929
import re
30+
import sys
31+
import typing
3032
from collections import OrderedDict, defaultdict
3133
from datetime import date
32-
from typing import Callable, Dict, Iterable, List, Optional, Tuple
34+
from typing import Callable, Dict, Iterable, List, Optional, Tuple, Type
3335

3436
from jinja2 import Environment, PackageLoader
37+
from packaging.version import InvalidVersion, Version
3538

3639
from commitizen import defaults
3740
from commitizen.bump import normalize_tag
3841
from commitizen.exceptions import InvalidConfigurationError, NoCommitsFoundError
3942
from commitizen.git import GitCommit, GitTag
4043

44+
if sys.version_info >= (3, 8):
45+
from commitizen.version_types import VersionProtocol
46+
else:
47+
# workaround mypy issue for 3.7 python
48+
VersionProtocol = typing.Any
49+
4150

4251
def get_commit_tag(commit: GitCommit, tags: List[GitTag]) -> Optional[GitTag]:
4352
return next((tag for tag in tags if tag.rev == commit.rev), None)
4453

4554

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+
4680
def generate_tree_from_commits(
4781
commits: List[GitCommit],
4882
tags: List[GitTag],
@@ -51,6 +85,7 @@ def generate_tree_from_commits(
5185
unreleased_version: Optional[str] = None,
5286
change_type_map: Optional[Dict[str, str]] = None,
5387
changelog_message_builder_hook: Optional[Callable] = None,
88+
merge_prerelease: bool = False,
5489
) -> Iterable[Dict]:
5590
pat = re.compile(changelog_pattern)
5691
map_pat = re.compile(commit_parser, re.MULTILINE)
@@ -73,15 +108,15 @@ def generate_tree_from_commits(
73108
for commit in commits:
74109
commit_tag = get_commit_tag(commit, tags)
75110

76-
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+
):
77114
used_tags.append(commit_tag)
78115
yield {
79116
"version": current_tag_name,
80117
"date": current_tag_date,
81118
"changes": changes,
82119
}
83-
# TODO: Check if tag matches the version pattern, otherwise skip it.
84-
# This in order to prevent tags that are not versions.
85120
current_tag_name = commit_tag.name
86121
current_tag_date = commit_tag.date
87122
changes = defaultdict(list)
@@ -286,7 +321,10 @@ def get_smart_tag_range(
286321

287322

288323
def get_oldest_and_newest_rev(
289-
tags: List[GitTag], version: str, tag_format: str
324+
tags: List[GitTag],
325+
version: str,
326+
tag_format: str,
327+
version_type_cls: Optional[Type[VersionProtocol]] = None,
290328
) -> Tuple[Optional[str], Optional[str]]:
291329
"""Find the tags for the given version.
292330
@@ -301,11 +339,15 @@ def get_oldest_and_newest_rev(
301339
except ValueError:
302340
newest = version
303341

304-
newest_tag = normalize_tag(newest, tag_format=tag_format)
342+
newest_tag = normalize_tag(
343+
newest, tag_format=tag_format, version_type_cls=version_type_cls
344+
)
305345

306346
oldest_tag = None
307347
if oldest:
308-
oldest_tag = normalize_tag(oldest, tag_format=tag_format)
348+
oldest_tag = normalize_tag(
349+
oldest, tag_format=tag_format, version_type_cls=version_type_cls
350+
)
309351

310352
tags_range = get_smart_tag_range(tags, newest=newest_tag, oldest=oldest_tag)
311353
if not tags_range:

commitizen/cli.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
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
89
from decli import cli
910

10-
from commitizen import commands, config, out
11+
from commitizen import commands, config, out, version_types
1112
from commitizen.exceptions import (
1213
CommitizenException,
1314
ExitCode,
@@ -202,6 +203,12 @@
202203
"help": "bump to the given version (e.g: 1.5.3)",
203204
"metavar": "MANUAL_VERSION",
204205
},
206+
{
207+
"name": ["--version-type"],
208+
"help": "choose version type",
209+
"default": None,
210+
"choices": version_types.VERSION_TYPES,
211+
},
205212
],
206213
},
207214
{
@@ -247,10 +254,19 @@
247254
"name": "--start-rev",
248255
"default": None,
249256
"help": (
250-
"start rev of the changelog."
257+
"start rev of the changelog. "
251258
"If not set, it will generate changelog from the start"
252259
),
253260
},
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+
},
254270
],
255271
},
256272
{
@@ -330,21 +346,22 @@
330346

331347

332348
def commitizen_excepthook(
333-
type, value, tracekback, debug=False, no_raise: List[int] = None
349+
type, value, traceback, debug=False, no_raise: List[int] = None
334350
):
351+
traceback = traceback if isinstance(traceback, TracebackType) else None
335352
if not no_raise:
336353
no_raise = []
337354
if isinstance(value, CommitizenException):
338355
if value.message:
339356
value.output_method(value.message)
340357
if debug:
341-
original_excepthook(type, value, tracekback)
358+
original_excepthook(type, value, traceback)
342359
exit_code = value.exit_code
343360
if exit_code in no_raise:
344361
exit_code = 0
345362
sys.exit(exit_code)
346363
else:
347-
original_excepthook(type, value, tracekback)
364+
original_excepthook(type, value, traceback)
348365

349366

350367
commitizen_debug_excepthook = partial(commitizen_excepthook, debug=True)

0 commit comments

Comments
 (0)