Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion commitizen/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ def normalize_tag(
version = self.scheme(version) if isinstance(version, str) else version
tag_format = tag_format or self.tag_format

major, minor, patch = version.release
release = list(version.release)
while len(release) < 3:
release.append(0)
major, minor, patch = release[:3]
prerelease = version.prerelease or ""

t = Template(tag_format)
Expand Down
20 changes: 20 additions & 0 deletions commitizen/version_schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,26 @@ def _get_increment_base(
return f"{self.major}.{self.minor}.{self.micro}"


class MonotonicVersion(BaseVersion):
"""
Monotonic versioning scheme

Any increment bump simply increases the single numeric component.
"""

parser: ClassVar[re.Pattern] = re.compile(
r"v?(?P<version>([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)"
)

def increment_base(self, increment: Increment | None = None) -> str:
return f"{self.major + 1}"

def _get_increment_base(
self, increment: Increment | None, exact_increment: bool
) -> str:
return self.increment_base(increment)


class Pep440(BaseVersion):
"""
PEP 440 Version Scheme
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ uv = "commitizen.providers:UvProvider"
pep440 = "commitizen.version_schemes:Pep440"
semver = "commitizen.version_schemes:SemVer"
semver2 = "commitizen.version_schemes:SemVer2"
monotonic = "commitizen.version_schemes:MonotonicVersion"

[dependency-groups]
dev = ["ipython>=8.0", "tox>4", "poethepoet>=0.34.0"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ usage: cz bump [-h] [--dry-run] [--files-only] [--local-version] [--changelog]
[--changelog-to-stdout] [--git-output-to-stderr] [--retry]
[--major-version-zero] [--template TEMPLATE] [--extra EXTRA]
[--file-name FILE_NAME] [--prerelease-offset PRERELEASE_OFFSET]
[--version-scheme {pep440,semver,semver2}]
[--version-type {pep440,semver,semver2}]
[--version-scheme {monotonic,pep440,semver,semver2}]
[--version-type {monotonic,pep440,semver,semver2}]
[--build-metadata BUILD_METADATA] [--get-next]
[--allow-no-commit]
[MANUAL_VERSION]
Expand Down Expand Up @@ -71,9 +71,9 @@ options:
file name of changelog (default: 'CHANGELOG.md')
--prerelease-offset PRERELEASE_OFFSET
start pre-releases with this offset
--version-scheme {pep440,semver,semver2}
--version-scheme {monotonic,pep440,semver,semver2}
choose version scheme
--version-type {pep440,semver,semver2}
--version-type {monotonic,pep440,semver,semver2}
Deprecated, use --version-scheme instead
--build-metadata BUILD_METADATA
Add additional build-metadata to the version-number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME]
[--unreleased-version UNRELEASED_VERSION] [--incremental]
[--start-rev START_REV] [--merge-prerelease]
[--version-scheme {pep440,semver,semver2}]
[--version-scheme {monotonic,pep440,semver,semver2}]
[--export-template EXPORT_TEMPLATE] [--template TEMPLATE]
[--extra EXTRA] [--tag-format TAG_FORMAT]
[rev_range]
Expand All @@ -28,7 +28,7 @@ options:
--merge-prerelease collect all changes from prereleases into next non-
prerelease. If not set, it will include prereleases in
the changelog
--version-scheme {pep440,semver,semver2}
--version-scheme {monotonic,pep440,semver,semver2}
choose version scheme
--export-template EXPORT_TEMPLATE
Export the changelog template into this file instead
Expand Down
6 changes: 6 additions & 0 deletions tests/test_bump_normalize_tag.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytest

from commitizen.tags import TagRules
from commitizen.version_schemes import MonotonicVersion

conversion = [
(("1.2.3", "v$version"), "v1.2.3"),
Expand All @@ -21,3 +22,8 @@ def test_create_tag(test_input, expected):
rules = TagRules()
new_tag = rules.normalize_tag(version, format)
assert new_tag == expected


def test_create_tag_monotonic_scheme():
rules = TagRules(MonotonicVersion)
assert rules.normalize_tag("4", "release-$version") == "release-4"
76 changes: 76 additions & 0 deletions tests/test_version_scheme_monotonic_versioning.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from __future__ import annotations

import pytest

from commitizen.version_schemes import MonotonicVersion, VersionProtocol
from tests.utils import VersionSchemeTestArgs


@pytest.mark.parametrize(
"version_args, expected_version",
[
(
VersionSchemeTestArgs(
current_version="1",
increment="PATCH",
prerelease=None,
prerelease_offset=0,
devrelease=None,
),
"2",
),
(
VersionSchemeTestArgs(
current_version="2",
increment="MINOR",
prerelease=None,
prerelease_offset=0,
devrelease=None,
),
"3",
),
(
VersionSchemeTestArgs(
current_version="3",
increment="MAJOR",
prerelease=None,
prerelease_offset=0,
devrelease=None,
),
"4",
),
(
VersionSchemeTestArgs(
current_version="10",
increment="PATCH",
prerelease=None,
prerelease_offset=0,
devrelease=None,
),
"11",
),
],
)
def test_bump_monotonic_version(
version_args: VersionSchemeTestArgs, expected_version: str
):
assert (
str(
MonotonicVersion(version_args.current_version).bump(
increment=version_args.increment,
prerelease=version_args.prerelease,
prerelease_offset=version_args.prerelease_offset,
devrelease=version_args.devrelease,
)
)
== expected_version
)


def test_monotonic_scheme_property():
version = MonotonicVersion("1")
assert version.scheme is MonotonicVersion


def test_monotonic_implements_version_protocol():
assert isinstance(MonotonicVersion("1"), VersionProtocol)
13 changes: 12 additions & 1 deletion tests/test_version_schemes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

from commitizen.config.base_config import BaseConfig
from commitizen.exceptions import VersionSchemeUnknown
from commitizen.version_schemes import Pep440, SemVer, get_version_scheme
from commitizen.version_schemes import (
MonotonicVersion,
Pep440,
SemVer,
get_version_scheme,
)


def test_default_version_scheme_is_pep440(config: BaseConfig):
Expand Down Expand Up @@ -52,6 +57,12 @@ def test_version_scheme_from_config_priority(config: BaseConfig):
assert scheme is Pep440


def test_version_scheme_monotonic(config: BaseConfig):
config.settings["version_scheme"] = "monotonic"
scheme = get_version_scheme(config.settings)
assert scheme is MonotonicVersion


def test_warn_if_version_protocol_not_implemented(
config: BaseConfig, mocker: MockerFixture
):
Expand Down