Repository: callowayproject/bump-my-version
Pull request #235 (2024-09-14 13:27:37)

Fixed missing new version info in some hook environments


Patch:
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 @@ import subprocess
 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),
     }
 
 


Test patch:
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 @@ import subprocess
 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 os
 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 @@ class TestBaseEnv:
         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<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\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<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\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)