diff --git a/CHANGELOG.md b/CHANGELOG.md index 061c057..b03bb5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Unreleased + +* Updated `Version.bump()` to add a `smart` argument, + which only bumps when `distance != 0`. + This will also make `Version.serialize()` use pre-release formatting automatically, + like calling `Version.serialize(bump=True)`. + ## v1.19.2 (2024-02-16) * Fixed an exception when a Git repository had a broken ref. diff --git a/dunamai/__init__.py b/dunamai/__init__.py index e09e4b4..f30ccc3 100644 --- a/dunamai/__init__.py +++ b/dunamai/__init__.py @@ -597,6 +597,7 @@ def __init__( self._matched_tag = None # type: Optional[str] self._newer_unmatched_tags = None # type: Optional[Sequence[str]] + self._smart_bumped = False def __str__(self) -> str: return self.serialize() @@ -729,8 +730,8 @@ def serialize( """ base = self.base revision = self.revision - if bump and self.distance > 0: - bumped = self.bump() + if bump: + bumped = self.bump(smart=True) base = bumped.base revision = bumped.revision @@ -782,7 +783,7 @@ def serialize( if revision is not None: pre_parts.append(str(revision)) if self.distance > 0: - pre_parts.append("pre" if bump else "post") + pre_parts.append("pre" if bump or self._smart_bumped else "post") pre_parts.append(str(self.distance)) if style == Style.Pep440: @@ -796,7 +797,7 @@ def serialize( stage = None dev = revision if self.distance > 0: - if bump: + if bump or self._smart_bumped: if dev is None: dev = self.distance else: @@ -914,7 +915,7 @@ def parse(cls, version: str, pattern: Union[str, Pattern] = Pattern.Default) -> epoch=epoch, ) - def bump(self, index: int = -1, increment: int = 1) -> "Version": + def bump(self, index: int = -1, increment: int = 1, smart: bool = False) -> "Version": """ Increment the version. @@ -927,9 +928,18 @@ def bump(self, index: int = -1, increment: int = 1) -> "Version": the right side and count down from -1. Only has an effect when the base is bumped. :param increment: By how much to increment the relevant position. + :param smart: If true, only bump when distance is not 0. + This will also make `Version.serialize()` use pre-release formatting automatically, + like calling `Version.serialize(bump=True)`. :returns: Bumped version. """ bumped = copy.deepcopy(self) + + if smart: + if bumped.distance == 0: + return bumped + bumped._smart_bumped = True + if bumped.stage is None: bumped.base = bump_version(bumped.base, index, increment) else: diff --git a/tests/unit/test_dunamai.py b/tests/unit/test_dunamai.py index e30ff0b..b097f1e 100644 --- a/tests/unit/test_dunamai.py +++ b/tests/unit/test_dunamai.py @@ -508,6 +508,14 @@ def test__version__bump() -> None: assert Version("1.2.3", stage=("a", None)).bump().serialize() == "1.2.3a2" assert Version("1.2.3", stage=("a", 4)).bump().serialize() == "1.2.3a5" + assert Version("1.2.3", distance=0).bump(smart=False).serialize() == "1.2.4" + assert Version("1.2.3", distance=0).bump(smart=True).serialize() == "1.2.3" + assert Version("1.2.3", distance=0).serialize(bump=True) == "1.2.3" + + assert Version("1.2.3", distance=5).bump(smart=False).serialize() == "1.2.4.post5.dev0" + assert Version("1.2.3", distance=5).bump(smart=True).serialize() == "1.2.4.dev5" + assert Version("1.2.3", distance=5).serialize(bump=True) == "1.2.4.dev5" + def test__version__parse(): assert Version.parse("1.2.3") == Version("1.2.3")