diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 55836498a0..6556a068ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,7 @@ repos: exclude: "poetry.lock" - repo: https://github.com/commitizen-tools/commitizen - rev: v3.14.0 # automatically updated by Commitizen + rev: v3.14.1 # automatically updated by Commitizen hooks: - id: commitizen - id: commitizen-branch diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ad6367e31..db06703c98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,11 @@ +## v3.14.1 (2024-02-04) + +### Fix + +- **bump**: remove unused method +- **scm**: only search tags that are reachable by the current commit + ## v3.14.0 (2024-02-01) ### Feat diff --git a/commitizen/__version__.py b/commitizen/__version__.py index 382c7be006..237d3a709b 100644 --- a/commitizen/__version__.py +++ b/commitizen/__version__.py @@ -1 +1 @@ -__version__ = "3.14.0" +__version__ = "3.14.1" diff --git a/commitizen/changelog.py b/commitizen/changelog.py index cd9e76a320..e4273db93a 100644 --- a/commitizen/changelog.py +++ b/commitizen/changelog.py @@ -24,6 +24,7 @@ - [x] hook after changelog is generated (api calls) - [x] add support for change_type maps """ + from __future__ import annotations import re diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index b2ecd3130f..2b108b26c5 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -27,7 +27,6 @@ from commitizen.version_schemes import ( get_version_scheme, InvalidVersion, - VersionProtocol, ) logger = getLogger("commitizen") @@ -397,33 +396,3 @@ def _get_commit_args(self): if self.no_verify: commit_args.append("--no-verify") return " ".join(commit_args) - - def find_previous_final_version( - self, current_version: VersionProtocol - ) -> VersionProtocol | None: - tag_format: str = self.bump_settings["tag_format"] - current = bump.normalize_tag( - current_version, - tag_format=tag_format, - scheme=self.scheme, - ) - - final_versions = [] - for tag in git.get_tag_names(): - assert tag - try: - version = self.scheme(tag) - if not version.is_prerelease or tag == current: - final_versions.append(version) - except InvalidVersion: - continue - - if not final_versions: - return None - - final_versions = sorted(final_versions) # type: ignore [type-var] - current_index = final_versions.index(current_version) - previous_index = current_index - 1 - if previous_index < 0: - return None - return final_versions[previous_index] diff --git a/commitizen/cz/base.py b/commitizen/cz/base.py index d9bf5ea4a0..14d9e5a522 100644 --- a/commitizen/cz/base.py +++ b/commitizen/cz/base.py @@ -37,9 +37,9 @@ class BaseCommitizen(metaclass=ABCMeta): change_type_order: list[str] | None = None # Executed per message parsed by the commitizen - changelog_message_builder_hook: None | ( - Callable[[dict, git.GitCommit], dict] - ) = None + changelog_message_builder_hook: None | (Callable[[dict, git.GitCommit], dict]) = ( + None + ) # Executed only at the end of the changelog generation changelog_hook: Callable[[str, str | None], str] | None = None diff --git a/commitizen/cz/exceptions.py b/commitizen/cz/exceptions.py index 2597b68813..d74f39aaaa 100644 --- a/commitizen/cz/exceptions.py +++ b/commitizen/cz/exceptions.py @@ -1,6 +1,4 @@ -class CzException(Exception): - ... +class CzException(Exception): ... -class AnswerRequiredError(CzException): - ... +class AnswerRequiredError(CzException): ... diff --git a/commitizen/git.py b/commitizen/git.py index 4c4dfdb961..6cdc7e2752 100644 --- a/commitizen/git.py +++ b/commitizen/git.py @@ -164,7 +164,9 @@ def get_filenames_in_commit(git_reference: str = ""): raise GitCommandError(c.err) -def get_tags(dateformat: str = "%Y-%m-%d") -> list[GitTag]: +def get_tags( + dateformat: str = "%Y-%m-%d", reachable_only: bool = False +) -> list[GitTag]: inner_delimiter = "---inner_delimiter---" formatter = ( f'"%(refname:lstrip=2){inner_delimiter}' @@ -172,8 +174,12 @@ def get_tags(dateformat: str = "%Y-%m-%d") -> list[GitTag]: f"%(creatordate:format:{dateformat}){inner_delimiter}" f'%(object)"' ) - c = cmd.run(f"git tag --format={formatter} --sort=-creatordate") + extra = "--merged" if reachable_only else "" + c = cmd.run(f"git tag --format={formatter} --sort=-creatordate {extra}") if c.return_code != 0: + if reachable_only and c.err == "fatal: malformed object name HEAD\n": + # this can happen if there are no commits in the repo yet + return [] raise GitCommandError(c.err) if c.err: diff --git a/commitizen/providers/scm_provider.py b/commitizen/providers/scm_provider.py index bc9dda4b8a..37329d07a5 100644 --- a/commitizen/providers/scm_provider.py +++ b/commitizen/providers/scm_provider.py @@ -1,11 +1,16 @@ from __future__ import annotations import re -from typing import Callable, cast +from typing import Callable from commitizen.git import get_tags -from commitizen.version_schemes import get_version_scheme +from commitizen.version_schemes import ( + get_version_scheme, + InvalidVersion, + Version, + VersionProtocol, +) from commitizen.providers.base_provider import VersionProvider @@ -28,7 +33,7 @@ class ScmProvider(VersionProvider): "$devrelease": r"(?P\.dev\d+)?", } - def _tag_format_matcher(self) -> Callable[[str], str | None]: + def _tag_format_matcher(self) -> Callable[[str], VersionProtocol | None]: version_scheme = get_version_scheme(self.config) pattern = self.config.settings["tag_format"] if pattern == "$version": @@ -38,15 +43,15 @@ def _tag_format_matcher(self) -> Callable[[str], str | None]: regex = re.compile(f"^{pattern}$", re.VERBOSE) - def matcher(tag: str) -> str | None: + def matcher(tag: str) -> Version | None: match = regex.match(tag) if not match: return None groups = match.groupdict() if "version" in groups: - return groups["version"] + ver = groups["version"] elif "major" in groups: - return "".join( + ver = "".join( ( groups["major"], f".{groups['minor']}" if groups.get("minor") else "", @@ -56,16 +61,27 @@ def matcher(tag: str) -> str | None: ) ) elif pattern == version_scheme.parser.pattern: - return str(version_scheme(tag)) - return None + ver = tag + else: + return None + + try: + return version_scheme(ver) + except InvalidVersion: + return None return matcher def get_version(self) -> str: matcher = self._tag_format_matcher() - return next( - (cast(str, matcher(t.name)) for t in get_tags() if matcher(t.name)), "0.0.0" + matches = sorted( + version + for t in get_tags(reachable_only=True) + if (version := matcher(t.name)) ) + if not matches: + return "0.0.0" + return str(matches[-1]) def set_version(self, version: str): # Not necessary diff --git a/commitizen/version_schemes.py b/commitizen/version_schemes.py index c277d2efc4..8fcec9e74f 100644 --- a/commitizen/version_schemes.py +++ b/commitizen/version_schemes.py @@ -4,7 +4,7 @@ import sys import warnings from itertools import zip_longest -from typing import TYPE_CHECKING, ClassVar, Protocol, Type, cast, runtime_checkable +from typing import TYPE_CHECKING, Any, ClassVar, Protocol, Type, cast, runtime_checkable import importlib_metadata as metadata from packaging.version import InvalidVersion # noqa: F401: Rexpose the common exception @@ -93,6 +93,24 @@ def micro(self) -> int: """The third item of :attr:`release` or ``0`` if unavailable.""" raise NotImplementedError("must be implemented") + def __lt__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __le__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __eq__(self, other: object) -> bool: + raise NotImplementedError("must be implemented") + + def __ge__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __gt__(self, other: Any) -> bool: + raise NotImplementedError("must be implemented") + + def __ne__(self, other: object) -> bool: + raise NotImplementedError("must be implemented") + def bump( self, increment: str, diff --git a/poetry.lock b/poetry.lock index 4ff2455fbd..d0be3bc97b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -73,33 +73,33 @@ files = [ [[package]] name = "black" -version = "23.12.1" +version = "24.1.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, + {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, + {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, + {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, + {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, + {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, + {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, + {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, + {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, + {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, + {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, + {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, + {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, + {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, + {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, + {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, + {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, + {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, + {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, + {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, + {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, + {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, + {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, ] [package.dependencies] @@ -1407,28 +1407,28 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "ruff" -version = "0.1.15" +version = "0.2.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, - {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, - {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, - {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, - {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"}, + {file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"}, + {file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"}, + {file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"}, + {file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"}, ] [[package]] @@ -1766,4 +1766,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8" -content-hash = "48784ae66f8098a8edaf69c3a1c49c5bf564cf94eda4ca7a20914675674afd18" +content-hash = "ae231a49c0c27985defdc7adba7a112eecc8c8abe1e9a8e5cf5358f7a71637c0" diff --git a/pyproject.toml b/pyproject.toml index 7c3266469c..455693e9b6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.commitizen] -version = "3.14.0" +version = "3.14.1" tag_format = "v$version" version_files = [ "pyproject.toml:version", @@ -9,7 +9,7 @@ version_files = [ [tool.poetry] name = "commitizen" -version = "3.14.0" +version = "3.14.1" description = "Python commitizen client tool" authors = ["Santiago Fraire "] license = "MIT" @@ -60,9 +60,9 @@ pytest-regressions = "^2.4.0" pytest-freezer = "^0.4.6" pytest-xdist = "^3.1.0" # code formatter -black = "~=23.11" +black = ">=23.11,<25.0" # linter -ruff = "~=0.1.6" +ruff = ">=0.1.6,<0.3.0" pre-commit = ">=2.18,<4.0" mypy = "^1.4" types-PyYAML = ">=5.4.3,<7.0.0" @@ -141,6 +141,8 @@ addopts = "--strict-markers" [tool.ruff] line-length = 88 + +[tool.ruff.lint] select = ["E", "F", "UP"] ignore = [ "E501", @@ -148,10 +150,10 @@ ignore = [ "D415" ] -[tool.ruff.isort] +[tool.ruff.lint.isort] known-first-party = ["commitizen", "tests"] -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" [tool.mypy] diff --git a/tests/providers/test_scm_provider.py b/tests/providers/test_scm_provider.py index a0bfc46474..9611dd9ee0 100644 --- a/tests/providers/test_scm_provider.py +++ b/tests/providers/test_scm_provider.py @@ -6,7 +6,13 @@ from commitizen.config.base_config import BaseConfig from commitizen.providers import get_provider from commitizen.providers.scm_provider import ScmProvider -from tests.utils import create_file_and_commit, create_tag +from tests.utils import ( + create_branch, + create_file_and_commit, + create_tag, + merge_branch, + switch_branch, +) @pytest.mark.parametrize( @@ -22,7 +28,8 @@ # much more lenient but require a v prefix. ("v$version", "v0.1.0", "0.1.0"), ("v$version", "no-match-because-no-v-prefix", "0.0.0"), - ("v$version", "v-match-TAG_FORMAT_REGEXS", "-match-TAG_FORMAT_REGEXS"), + # no match because not a valid version + ("v$version", "v-match-TAG_FORMAT_REGEXS", "0.0.0"), ("version-$version", "version-0.1.0", "0.1.0"), ("version-$version", "version-0.1", "0.1"), ("version-$version", "version-0.1.0rc1", "0.1.0rc1"), @@ -62,3 +69,48 @@ def test_scm_provider_default_without_commits_and_tags(config: BaseConfig): provider = get_provider(config) assert isinstance(provider, ScmProvider) assert provider.get_version() == "0.0.0" + + +@pytest.mark.usefixtures("tmp_git_project") +def test_scm_provider_default_with_commits_and_tags(config: BaseConfig): + config.settings["version_provider"] = "scm" + + provider = get_provider(config) + assert isinstance(provider, ScmProvider) + assert provider.get_version() == "0.0.0" + + create_file_and_commit("Initial state") + create_tag("1.0.0") + # create develop + create_branch("develop") + switch_branch("develop") + + # add a feature to develop + create_file_and_commit("develop: add beta feature1") + assert provider.get_version() == "1.0.0" + create_tag("1.1.0b0") + + # create staging + create_branch("staging") + switch_branch("staging") + create_file_and_commit("staging: Starting release candidate") + assert provider.get_version() == "1.1.0b0" + create_tag("1.1.0rc0") + + # add another feature to develop + switch_branch("develop") + create_file_and_commit("develop: add beta feature2") + assert provider.get_version() == "1.1.0b0" + create_tag("1.2.0b0") + + # add a hotfix to master + switch_branch("master") + create_file_and_commit("master: add hotfix") + assert provider.get_version() == "1.0.0" + create_tag("1.0.1") + + # merge the hotfix to staging + switch_branch("staging") + merge_branch("master") + + assert provider.get_version() == "1.1.0rc0" diff --git a/tests/test_bump_find_increment.py b/tests/test_bump_find_increment.py index 8e8fc2705e..ff24ff17a7 100644 --- a/tests/test_bump_find_increment.py +++ b/tests/test_bump_find_increment.py @@ -2,6 +2,7 @@ CC: Conventional commits SVE: Semantic version at the end """ + import pytest from commitizen import bump diff --git a/tests/test_changelog.py b/tests/test_changelog.py index 8aef10a31f..879443f334 100644 --- a/tests/test_changelog.py +++ b/tests/test_changelog.py @@ -1298,9 +1298,9 @@ def test_render_changelog_with_changelog_message_builder_hook( gitcommits, tags, any_changelog_format: ChangelogFormat ): def changelog_message_builder_hook(message: dict, commit: git.GitCommit) -> dict: - message[ - "message" - ] = f"{message['message']} [link](github.com/232323232) {commit.author} {commit.author_email}" + message["message"] = ( + f"{message['message']} [link](github.com/232323232) {commit.author} {commit.author_email}" + ) return message parser = ConventionalCommitsCz.commit_parser diff --git a/tests/test_cz_customize.py b/tests/test_cz_customize.py index 9f3556fce8..20a17b3d9c 100644 --- a/tests/test_cz_customize.py +++ b/tests/test_cz_customize.py @@ -498,7 +498,8 @@ def test_answer_unicode(config_with_unicode): } message = cz.message(answers) assert ( - message == "✨ feature: this feature enables customization through a config file" + message + == "✨ feature: this feature enables customization through a config file" ) cz = CustomizeCommitsCz(config_with_unicode) @@ -574,7 +575,8 @@ def test_commit_parser(config): def test_commit_parser_unicode(config_with_unicode): cz = CustomizeCommitsCz(config_with_unicode) assert ( - cz.commit_parser == "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" + cz.commit_parser + == "^(?P✨ feature|🐛 bug fix):\\s(?P.*)?" ) diff --git a/tests/test_git.py b/tests/test_git.py index 4ae11a45dd..79eb49f10c 100644 --- a/tests/test_git.py +++ b/tests/test_git.py @@ -9,7 +9,13 @@ from commitizen import cmd, exceptions, git from pytest_mock import MockFixture -from tests.utils import FakeCommand, create_file_and_commit, create_tag +from tests.utils import ( + FakeCommand, + create_file_and_commit, + create_tag, + create_branch, + switch_branch, +) def test_git_object_eq(): @@ -42,6 +48,29 @@ def test_get_tags(mocker: MockFixture): assert git.get_tags() == [] +def test_get_reachable_tags(tmp_commitizen_project): + with tmp_commitizen_project.as_cwd(): + create_file_and_commit("Initial state") + create_tag("1.0.0") + # create develop + create_branch("develop") + switch_branch("develop") + + # add a feature to develop + create_file_and_commit("develop") + create_tag("1.1.0b0") + + # create staging + switch_branch("master") + create_file_and_commit("master") + create_tag("1.0.1") + + tags = git.get_tags(reachable_only=True) + tag_names = set([t.name for t in tags]) + # 1.1.0b0 is not present + assert tag_names == {"1.0.0", "1.0.1"} + + def test_get_tag_names(mocker: MockFixture): tag_str = "v1.0.0\n" "v0.5.0\n" "v0.0.1\n" mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=tag_str)) diff --git a/tests/test_version_scheme_pep440.py b/tests/test_version_scheme_pep440.py index aa2120fad4..ac99450652 100644 --- a/tests/test_version_scheme_pep440.py +++ b/tests/test_version_scheme_pep440.py @@ -1,6 +1,8 @@ import itertools +import random import pytest + from commitizen.version_schemes import Pep440, VersionProtocol simple_flow = [ @@ -140,6 +142,29 @@ ] +# test driven development +sortability = [ + "0.10.0a0", + "0.1.1", + "0.1.2", + "2.1.1", + "3.0.0", + "0.9.1a0", + "1.0.0a1", + "1.0.0b1", + "1.0.0a1", + "1.0.0a2.dev1", + "1.0.0rc2", + "1.0.0a3.dev0", + "1.0.0a2.dev0", + "1.0.0a3.dev1", + "1.0.0a2.dev0", + "1.0.0b0", + "1.0.0rc0", + "1.0.0rc1", +] + + @pytest.mark.parametrize( "test_input,expected", itertools.chain( @@ -198,3 +223,76 @@ def test_pep440_scheme_property(): def test_pep440_implement_version_protocol(): assert isinstance(Pep440("0.0.1"), VersionProtocol) + + +def test_pep440_sortable(): + test_input = [x[0][0] for x in simple_flow] + test_input.extend([x[1] for x in simple_flow]) + # randomize + random_input = [Pep440(x) for x in random.sample(test_input, len(test_input))] + assert len(random_input) == len(test_input) + sorted_result = [str(x) for x in sorted(random_input)] + assert sorted_result == [ + "0.1.0", + "0.1.0", + "0.1.1.dev1", + "0.1.1", + "0.1.1", + "0.2.0", + "0.2.0", + "0.2.0", + "0.3.0.dev1", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a0", + "0.3.1a1", + "0.3.1a1", + "0.3.1a1", + "0.3.1", + "0.3.1", + "0.3.1", + "0.3.2", + "0.4.2", + "1.0.0a0", + "1.0.0a0", + "1.0.0a1", + "1.0.0a1", + "1.0.0a1", + "1.0.0a1", + "1.0.0a2.dev0", + "1.0.0a2.dev0", + "1.0.0a2.dev1", + "1.0.0a2", + "1.0.0a3.dev0", + "1.0.0a3.dev0", + "1.0.0a3.dev1", + "1.0.0b0", + "1.0.0b0", + "1.0.0b0", + "1.0.0b1", + "1.0.0b1", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc0", + "1.0.0rc1.dev1", + "1.0.0rc1", + "1.0.0", + "1.0.0", + "1.0.1", + "1.0.1", + "1.0.2", + "1.0.2", + "1.1.0", + "1.1.0", + "1.2.0", + "1.2.0", + "1.2.1", + "1.2.1", + "2.0.0", + ] diff --git a/tests/test_version_scheme_semver.py b/tests/test_version_scheme_semver.py index 85cfcf5df1..a0d6e14b50 100644 --- a/tests/test_version_scheme_semver.py +++ b/tests/test_version_scheme_semver.py @@ -1,4 +1,5 @@ import itertools +import random import pytest @@ -135,3 +136,76 @@ def test_semver_scheme_property(): def test_semver_implement_version_protocol(): assert isinstance(SemVer("0.0.1"), VersionProtocol) + + +def test_semver_sortable(): + test_input = [x[0][0] for x in simple_flow] + test_input.extend([x[1] for x in simple_flow]) + # randomize + random_input = [SemVer(x) for x in random.sample(test_input, len(test_input))] + assert len(random_input) == len(test_input) + sorted_result = [str(x) for x in sorted(random_input)] + assert sorted_result == [ + "0.1.0", + "0.1.0", + "0.1.1-dev1", + "0.1.1", + "0.1.1", + "0.2.0", + "0.2.0", + "0.2.0", + "0.3.0-dev1", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a0", + "0.3.1-a1", + "0.3.1-a1", + "0.3.1-a1", + "0.3.1", + "0.3.1", + "0.3.1", + "0.3.2", + "0.4.2", + "1.0.0-a0", + "1.0.0-a0", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a1", + "1.0.0-a2-dev0", + "1.0.0-a2-dev0", + "1.0.0-a2-dev1", + "1.0.0-a2", + "1.0.0-a3-dev0", + "1.0.0-a3-dev0", + "1.0.0-a3-dev1", + "1.0.0-b0", + "1.0.0-b0", + "1.0.0-b0", + "1.0.0-b1", + "1.0.0-b1", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc0", + "1.0.0-rc1-dev1", + "1.0.0-rc1", + "1.0.0", + "1.0.0", + "1.0.1", + "1.0.1", + "1.0.2", + "1.0.2", + "1.1.0", + "1.1.0", + "1.2.0", + "1.2.0", + "1.2.1", + "1.2.1", + "2.0.0", + ]