Skip to content

Commit 54a9191

Browse files
committed
refactor(bump): to use VersionProtocol interface instead packaging.Version subclass
Signed-off-by: apkawa <apkawa@gmail.com>
1 parent 14d6ca9 commit 54a9191

File tree

2 files changed

+78
-16
lines changed

2 files changed

+78
-16
lines changed

commitizen/bump.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from commitizen.defaults import MAJOR, MINOR, PATCH, bump_message
1111
from commitizen.exceptions import CurrentVersionNotFoundError
1212
from commitizen.git import GitCommit, smart_open
13+
from commitizen.version_types import VersionProtocol
1314

1415

1516
def find_increment(
@@ -120,8 +121,8 @@ def generate_version(
120121
prerelease_offset: int = 0,
121122
devrelease: Optional[int] = None,
122123
is_local_version: bool = False,
123-
version_type_cls: Optional[Type[Version]] = None,
124-
) -> Version:
124+
version_type_cls: Optional[Type[VersionProtocol]] = None,
125+
) -> VersionProtocol:
125126
"""Based on the given increment a proper semver will be generated.
126127
127128
For now the rules and versioning scheme is based on
@@ -210,9 +211,9 @@ def _version_to_regex(version: str) -> str:
210211

211212

212213
def normalize_tag(
213-
version: Union[Version, str],
214+
version: Union[VersionProtocol, str],
214215
tag_format: Optional[str] = None,
215-
version_type_cls: Optional[Type[Version]] = None,
216+
version_type_cls: Optional[Type[VersionProtocol]] = None,
216217
) -> str:
217218
"""The tag and the software version might be different.
218219

commitizen/version_types.py

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,94 @@
1+
import sys
2+
import typing
3+
4+
if sys.version_info >= (3, 8):
5+
from typing import Protocol as _Protocol
6+
else:
7+
_Protocol = object
8+
19
from packaging.version import Version
210

311

4-
class SemVerVersion(Version):
12+
class VersionProtocol(_Protocol):
13+
def __init__(self, _version: typing.Union[Version, str]):
14+
raise NotImplementedError("must be implemented")
15+
16+
def __str__(self) -> str:
17+
raise NotImplementedError("must be implemented")
18+
19+
@property
20+
def release(self) -> typing.Tuple[int, ...]:
21+
raise NotImplementedError("must be implemented")
22+
23+
@property
24+
def is_prerelease(self) -> bool:
25+
raise NotImplementedError("must be implemented")
26+
27+
@property
28+
def pre(self) -> typing.Optional[typing.Tuple[str, int]]:
29+
raise NotImplementedError("must be implemented")
30+
31+
@property
32+
def local(self) -> typing.Optional[str]:
33+
raise NotImplementedError("must be implemented")
34+
35+
@property
36+
def public(self) -> str:
37+
raise NotImplementedError("must be implemented")
38+
39+
40+
class SemVerVersion(VersionProtocol):
41+
def __init__(self, version: str):
42+
self._version = Version(version)
43+
44+
@property
45+
def release(self) -> typing.Tuple[int, ...]:
46+
return self._version.release
47+
48+
@property
49+
def is_prerelease(self) -> bool:
50+
return self._version.is_prerelease
51+
52+
@property
53+
def pre(self) -> typing.Optional[typing.Tuple[str, int]]:
54+
return self._version.pre
55+
56+
@property
57+
def local(self) -> typing.Optional[str]:
58+
return self._version.local
59+
60+
@property
61+
def public(self) -> str:
62+
return self._version.public
63+
564
def __str__(self) -> str:
665
parts = []
766

67+
version = self._version
68+
869
# Epoch
9-
if self.epoch != 0:
10-
parts.append(f"{self.epoch}!")
70+
if version.epoch != 0:
71+
parts.append(f"{version.epoch}!")
1172

1273
# Release segment
13-
parts.append(".".join(str(x) for x in self.release))
74+
parts.append(".".join(str(x) for x in version.release))
1475

1576
# Pre-release
16-
if self.pre is not None:
17-
pre = "".join(str(x) for x in self.pre)
77+
if version.pre is not None:
78+
pre = "".join(str(x) for x in version.pre)
1879
parts.append(f"-{pre}")
1980

2081
# Post-release
21-
if self.post is not None:
22-
parts.append(f"-post{self.post}")
82+
if version.post is not None:
83+
parts.append(f"-post{version.post}")
2384

2485
# Development release
25-
if self.dev is not None:
26-
parts.append(f"-dev{self.dev}")
86+
if version.dev is not None:
87+
parts.append(f"-dev{version.dev}")
2788

2889
# Local version segment
29-
if self.local is not None:
30-
parts.append(f"+{self.local}")
90+
if version.local is not None:
91+
parts.append(f"+{version.local}")
3192

3293
return "".join(parts)
3394

0 commit comments

Comments
 (0)