diff --git a/commitizen/commands/init.py b/commitizen/commands/init.py index 62b3aec971..39efdea814 100644 --- a/commitizen/commands/init.py +++ b/commitizen/commands/init.py @@ -46,6 +46,10 @@ def is_python(self) -> bool: def is_rust_cargo(self) -> bool: return os.path.isfile("Cargo.toml") + @property + def is_maven_project(self) -> bool: + return os.path.isfile("pom.xml") + @property def is_npm_package(self) -> bool: return os.path.isfile("package.json") @@ -222,6 +226,7 @@ def _ask_version_provider(self) -> str: "commitizen": "commitizen: Fetch and set version in commitizen config (default)", "cargo": "cargo: Get and set version from Cargo.toml:project.version field", "composer": "composer: Get and set version from composer.json:project.version field", + "mvn": "mvn: Get and set version from pom.xml:project.version field", "npm": "npm: Get and set version from package.json:project.version field", "pep621": "pep621: Get and set version from pyproject.toml:project.version field", "poetry": "poetry: Get and set version from pyproject.toml:tool.poetry.version field", @@ -236,6 +241,8 @@ def _ask_version_provider(self) -> str: default_val = "pep621" elif self.project_info.is_rust_cargo: default_val = "cargo" + elif self.project_info.is_maven_project: + default_val = "mvn" elif self.project_info.is_npm_package: default_val = "npm" elif self.project_info.is_php_composer: diff --git a/commitizen/providers/__init__.py b/commitizen/providers/__init__.py index 51302d2b37..5d992ee816 100644 --- a/commitizen/providers/__init__.py +++ b/commitizen/providers/__init__.py @@ -11,6 +11,7 @@ from commitizen.providers.cargo_provider import CargoProvider from commitizen.providers.commitizen_provider import CommitizenProvider from commitizen.providers.composer_provider import ComposerProvider +from commitizen.providers.mvn_provider import MavenProvider from commitizen.providers.npm_provider import NpmProvider from commitizen.providers.pep621_provider import Pep621Provider from commitizen.providers.poetry_provider import PoetryProvider @@ -21,6 +22,7 @@ "CargoProvider", "CommitizenProvider", "ComposerProvider", + "MavenProvider", "NpmProvider", "Pep621Provider", "PoetryProvider", diff --git a/commitizen/providers/mvn_provider.py b/commitizen/providers/mvn_provider.py new file mode 100644 index 0000000000..d7363914f6 --- /dev/null +++ b/commitizen/providers/mvn_provider.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +import subprocess + +from commitizen.providers.base_provider import VersionProvider + + +class MavenProvider(VersionProvider): + """ + Maven version management + + ref: https://octopus.com/blog/maven-versioning-explained + + Major.Minor.Patch-BuildNumber-Qualifier + + Precedence: + - alpha or a + - beta or b + - milestone or m + - rc or cr + - snapshot + - (the empty string) or ga or final or release + - sp + """ + + FULL_VERSION_REGEX = r"(?P\d+)\.(?P\d+)\.(?P\d+)[\.-]?(?P\d+)?[\.-]?(?P\w+)?" + + TAG_FORMAT_REGEXS = { + "$version": r"(?P.+)", + "$major": r"(?P\d+)", + "$minor": r"(?P\d+)", + "$patch": r"(?P\d+)", + "$buildnumber": r"(?P\d+)?", + "$qualifier": r"(?P\w+)?", + } + + filename = "./pom.xml" + + def __run_cmd(self, cmd) -> str: + return ( + subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + .stdout.read() # type: ignore + .decode("utf-8") + .strip() + ) + + def get_version(self, file: str = filename) -> str: + return self.__run_cmd( + f"mvn help:evaluate -Dexpression=project.version -q -DforceStdout -f {file}" + ) + + def set_version(self, version: str, file: str = filename) -> None: + self.__run_cmd(f"mvn versions:set -DnewVersion={version} -f {file}") diff --git a/pyproject.toml b/pyproject.toml index b644753b1b..251a957f5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,7 @@ restructuredtext = "commitizen.changelog_formats.restructuredtext:RestructuredTe cargo = "commitizen.providers:CargoProvider" commitizen = "commitizen.providers:CommitizenProvider" composer = "commitizen.providers:ComposerProvider" +mvn = "commitizen.providers:MavenProvider" npm = "commitizen.providers:NpmProvider" pep621 = "commitizen.providers:Pep621Provider" poetry = "commitizen.providers:PoetryProvider" diff --git a/tests/data/sample_pom.xml b/tests/data/sample_pom.xml new file mode 100644 index 0000000000..50b9f372bd --- /dev/null +++ b/tests/data/sample_pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + + + org.springframework.boot + spring-boot-starter-parent + 3.1.0 + + + + + io.github.commitizen-tools + sample-maven-pom + 3.2.1 + pom + + + Sample Maven POM + This is a sample POM + + + ${app.url} + v@{project.version} + + + + + + hthttps://github.com/commitizen-tools/commitizen + + + 17 + + + 3.1.0 + + + + + + + org.springframework.boot + spring-boot-devtools + ${spring-boot.version} + true + + + org.springframework.boot + spring-boot-starter-actuator + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + + + diff --git a/tests/data/sample_pom_snapshot.xml b/tests/data/sample_pom_snapshot.xml new file mode 100644 index 0000000000..694683b0fa --- /dev/null +++ b/tests/data/sample_pom_snapshot.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + + + org.springframework.boot + spring-boot-starter-parent + 3.1.0 + + + + + io.github.commitizen-tools + sample-maven-pom + 3.2.1-SNAPSHOT + pom + + + Sample Maven POM + This is a sample POM + + + ${app.url} + v@{project.version} + + + + + + hthttps://github.com/commitizen-tools/commitizen + + + 17 + + + 3.1.0 + + + + + + + org.springframework.boot + spring-boot-devtools + ${spring-boot.version} + true + + + org.springframework.boot + spring-boot-starter-actuator + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + pom + import + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + + + diff --git a/tests/providers/test_mvn_provider.py b/tests/providers/test_mvn_provider.py new file mode 100644 index 0000000000..014831de6a --- /dev/null +++ b/tests/providers/test_mvn_provider.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +import pytest + +import os + +from commitizen.config.base_config import BaseConfig +from commitizen.providers.mvn_provider import MavenProvider + + +def test_can_run_subcommand(config: BaseConfig): + provider = MavenProvider(config) + got = provider._MavenProvider__run_cmd("echo 'hi'") # type: ignore + expected = "hi" + assert got == expected + + +@pytest.mark.parametrize( + "file, expected", + ( + ("./tests/data/sample_pom.xml", "3.2.1"), + ("./tests/data/sample_pom_snapshot.xml", "3.2.1-SNAPSHOT"), + ), +) +def test_get_version(config: BaseConfig, file: str, expected: str): + provider = MavenProvider(config) + got = provider.get_version(file) + assert got == expected + + +def test_set_version(config: BaseConfig): + provider = MavenProvider(config) + file = "./tests/data/sample_pom.xml" + expected = "3.2.2" + provider.set_version(expected, file) + got = provider.get_version(file) + assert got == expected + + # rollback changes + expected = "3.2.1" + provider.set_version(expected, file) + got = provider.get_version(file) + assert got == expected + + # delete backup file created + backup_file = file + ".versionsBackup" + assert os.path.exists(backup_file) + if os.path.exists(backup_file): + os.remove(backup_file) + assert not os.path.exists(backup_file) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy