diff --git a/bumpversion/hooks.py b/bumpversion/hooks.py index 3238c019..26e32969 100644 --- a/bumpversion/hooks.py +++ b/bumpversion/hooks.py @@ -6,6 +6,7 @@ from typing import Dict, List, Optional from bumpversion.config.models import Config +from bumpversion.context import get_context from bumpversion.ui import get_indented_logger from bumpversion.versioning.models import Version @@ -52,6 +53,15 @@ def version_env(version: Version, version_prefix: str) -> Dict[str, str]: return {f"{PREFIX}{version_prefix}{part.upper()}": version[part].value for part in version} +def new_version_env(config: Config, current_version: Version, new_version: Version) -> Dict[str, str]: + """Provide the environment dictionary for new_version serialized and tag name.""" + ctx = get_context(config, current_version, new_version) + new_version_string = config.version_config.serialize(new_version, ctx) + ctx["new_version"] = new_version_string + new_version_tag = config.tag_name.format(**ctx) + return {f"{PREFIX}NEW_VERSION": new_version_string, f"{PREFIX}NEW_VERSION_TAG": new_version_tag} + + def get_setup_hook_env(config: Config, current_version: Version) -> Dict[str, str]: """Provide the environment dictionary for `setup_hook`s.""" return {**base_env(config), **scm_env(config), **version_env(current_version, "CURRENT_")} @@ -64,6 +74,7 @@ def get_pre_commit_hook_env(config: Config, current_version: Version, new_versio **scm_env(config), **version_env(current_version, "CURRENT_"), **version_env(new_version, "NEW_"), + **new_version_env(config, current_version, new_version), } @@ -74,6 +85,7 @@ def get_post_commit_hook_env(config: Config, current_version: Version, new_versi **scm_env(config), **version_env(current_version, "CURRENT_"), **version_env(new_version, "NEW_"), + **new_version_env(config, current_version, new_version), } diff --git a/tests/conftest.py b/tests/conftest.py index 680b5a55..10a7285e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,11 +4,12 @@ from contextlib import contextmanager from click.testing import CliRunner from pathlib import Path -from typing import Generator +from typing import Generator, Tuple import pytest - +from bumpversion.config import Config from bumpversion.versioning.models import Version +from bumpversion.versioning.version_config import VersionConfig @pytest.fixture @@ -41,10 +42,9 @@ def inside_dir(dirpath: Path) -> Generator: os.chdir(old_path) -def get_config_data(overrides: dict) -> tuple: +def get_config_data(overrides: dict) -> Tuple[Config, VersionConfig, Version]: """Get the configuration, version_config and version.""" from bumpversion import config - from bumpversion.versioning.version_config import VersionConfig conf = config.get_configuration(config_file="missing", **overrides) version_config = VersionConfig(conf.parse, conf.serialize, conf.search, conf.replace, conf.parts) diff --git a/tests/test_hooks/test_envs.py b/tests/test_hooks/test_envs.py index 3570b7f2..726a0765 100644 --- a/tests/test_hooks/test_envs.py +++ b/tests/test_hooks/test_envs.py @@ -5,10 +5,52 @@ import subprocess from pathlib import Path -from bumpversion.hooks import scm_env, PREFIX, base_env, version_env +from bumpversion.hooks import ( + scm_env, + PREFIX, + base_env, + version_env, + new_version_env, + get_setup_hook_env, + get_pre_commit_hook_env, +) from tests.conftest import inside_dir, get_config_data +def assert_os_environ_items_included(result_env: dict) -> None: + """Assert that the OS environment variables are in the result.""" + for var, value in os.environ.items(): + assert var in result_env + assert result_env[var] == value + + +def assert_scm_info_included(result_env: dict): + """Assert the SCM information is included in the result.""" + assert f"{PREFIX}COMMIT_SHA" in result_env + assert f"{PREFIX}DISTANCE_TO_LATEST_TAG" in result_env + assert f"{PREFIX}IS_DIRTY" in result_env + assert f"{PREFIX}BRANCH_NAME" in result_env + assert f"{PREFIX}SHORT_BRANCH_NAME" in result_env + assert f"{PREFIX}CURRENT_VERSION" in result_env + assert f"{PREFIX}CURRENT_TAG" in result_env + + +def assert_current_version_info_included(result_env: dict): + """Assert the current version information is included in the result.""" + assert f"{PREFIX}CURRENT_MAJOR" in result_env + assert f"{PREFIX}CURRENT_MINOR" in result_env + assert f"{PREFIX}CURRENT_PATCH" in result_env + + +def assert_new_version_info_included(result_env: dict): + """Assert the new version information is included in the result.""" + assert f"{PREFIX}NEW_MAJOR" in result_env + assert f"{PREFIX}NEW_MINOR" in result_env + assert f"{PREFIX}NEW_PATCH" in result_env + assert f"{PREFIX}NEW_VERSION" in result_env + assert f"{PREFIX}NEW_VERSION_TAG" in result_env + + def test_scm_env_returns_correct_info(git_repo: Path): """Should return information about the latest tag.""" readme = git_repo.joinpath("readme.md") @@ -58,26 +100,18 @@ def test_includes_os_environ(self): config, _, _ = get_config_data({"current_version": "0.1.0"}) result_env = base_env(config) - for var, value in os.environ.items(): - assert var in result_env - assert result_env[var] == value + assert_os_environ_items_included(result_env) def test_includes_scm_info(self): """The output includes SCM information.""" config, _, _ = get_config_data({"current_version": "0.1.0"}) result_env = base_env(config) - assert f"{PREFIX}COMMIT_SHA" in result_env - assert f"{PREFIX}DISTANCE_TO_LATEST_TAG" in result_env - assert f"{PREFIX}IS_DIRTY" in result_env - assert f"{PREFIX}BRANCH_NAME" in result_env - assert f"{PREFIX}SHORT_BRANCH_NAME" in result_env - assert f"{PREFIX}CURRENT_VERSION" in result_env - assert f"{PREFIX}CURRENT_TAG" in result_env + assert_scm_info_included(result_env) def test_current_version_env_includes_correct_info(): - """pass""" + """The version_env for a version should include all its parts""" config, _, current_version = get_config_data( {"current_version": "0.1.0", "parse": r"(?P\d+)\.(?P\d+)\.(?P\d+)"} ) @@ -86,3 +120,38 @@ def test_current_version_env_includes_correct_info(): assert result[f"{PREFIX}CURRENT_MAJOR"] == "0" assert result[f"{PREFIX}CURRENT_MINOR"] == "1" assert result[f"{PREFIX}CURRENT_PATCH"] == "0" + + +def test_new_version_env_includes_correct_info(): + """The new_version_env should return the serialized version and tag name.""" + + config, _, current_version = get_config_data( + {"current_version": "0.1.0", "parse": r"(?P\d+)\.(?P\d+)\.(?P\d+)"} + ) + new_version = current_version.bump("minor") + result = new_version_env(config, current_version, new_version) + + assert result[f"{PREFIX}NEW_VERSION"] == "0.2.0" + assert result[f"{PREFIX}NEW_VERSION_TAG"] == "v0.2.0" + + +def test_get_setup_hook_env_includes_correct_info(): + """The setup hook environment should contain specific information.""" + config, _, current_version = get_config_data({"current_version": "0.1.0"}) + result_env = get_setup_hook_env(config, current_version) + + assert_os_environ_items_included(result_env) + assert_scm_info_included(result_env) + assert_current_version_info_included(result_env) + + +def test_get_pre_commit_hook_env_includes_correct_info(): + """The pre-commit hook environment should contain specific information.""" + config, _, current_version = get_config_data({"current_version": "0.1.0"}) + new_version = current_version.bump("minor") + result_env = get_pre_commit_hook_env(config, current_version, new_version) + + assert_os_environ_items_included(result_env) + assert_scm_info_included(result_env) + assert_current_version_info_included(result_env) + assert_new_version_info_included(result_env)