Skip to content

Commit

Permalink
Add handling for git path addition with new test coverage
Browse files Browse the repository at this point in the history
Enhances the `Git` class by adding the `add_path` method, improving control over tracked files. Includes comprehensive test cases to validate subpath handling, handle command failures, and ensure robustness against invalid inputs. Also includes minor refactoring with updated exception handling and code comments.
  • Loading branch information
coordt committed Jan 26, 2025
1 parent d701c1f commit 8ad5c82
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 4 deletions.
11 changes: 8 additions & 3 deletions bumpversion/scm/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ def get_all_tags(self) -> list[str]:
try:
result = run_command(self._ALL_TAGS_COMMAND)
return result.stdout.splitlines()
except (FileNotFoundError, PermissionError, NotADirectoryError, subprocess.CalledProcessError):
except ( # pragma: no-coverage
FileNotFoundError,
PermissionError,
NotADirectoryError,
subprocess.CalledProcessError,
):
return []

def commit_and_tag(self, files: list[Path | str], context: MutableMapping, dry_run: bool = False) -> None:
Expand Down Expand Up @@ -109,9 +114,9 @@ def commit(self, context: MutableMapping) -> None:
new_version = context.get("new_version", "")
commit_message = self.config.message.format(**context)

if not current_version:
if not current_version: # pragma: no-coverage
logger.warning("No current version given, using an empty string.")
if not new_version:
if not new_version: # pragma: no-coverage
logger.warning("No new version given, using an empty string.")

with NamedTemporaryFile("wb", delete=False) as f:
Expand Down
71 changes: 70 additions & 1 deletion tests/test_scm/test_git.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
"""Tests for bumpversion.scm.git."""

import subprocess

Check warning on line 3 in tests/test_scm/test_git.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tests/test_scm/test_git.py#L3

Consider possible security implications associated with the subprocess module.
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest
from pytest import param

from bumpversion.exceptions import DirtyWorkingDirectoryError
from bumpversion.exceptions import BumpVersionError, DirtyWorkingDirectoryError
from bumpversion.scm.git import Git, assert_nondirty, commit_info, moveable_tag, revision_info, tag
from bumpversion.scm.models import LatestTagInfo, SCMConfig
from bumpversion.utils import run_command
Expand Down Expand Up @@ -70,6 +72,73 @@ def test_returns_correct_commit_and_tag_info(self, git_repo: Path, scm_config: S
assert tag_info.repository_root == git_repo
assert tag_info.dirty is False

class TestGitAddPath:
"""Tests for the add_path method in the Git class."""

@patch("bumpversion.scm.git.run_command")
@patch("bumpversion.scm.git.Git.latest_tag_info")
@patch("bumpversion.scm.git.is_subpath")
def test_valid_subpath_is_added(
self, mock_is_subpath, mock_latest_tag_info, mock_run_command, scm_config: SCMConfig, tmp_path: Path
):
"""A path that is a subpath of the repository root should be added."""
# Arrange
repository_root = tmp_path / "repository"
repository_root.mkdir()
path_to_add = repository_root / "file.txt"
mock_latest_tag_info.return_value.repository_root = repository_root
mock_is_subpath.return_value = True
mock_run_command.return_value = None
git_instance = Git(scm_config)

# Act
with inside_dir(repository_root):
git_instance.add_path(path_to_add)

# Assert
mock_run_command.assert_called_once_with(["git", "add", "--update", "file.txt"])

@patch("bumpversion.scm.git.run_command")
@patch("bumpversion.scm.git.Git.latest_tag_info")
@patch("bumpversion.scm.git.is_subpath")
def test_invalid_subpath_is_not_added(
self, mock_is_subpath, mock_latest_tag_info, mock_run_command, scm_config, tmp_path: Path
):
"""A path that is not a subpath of the repository root should not be added."""
# Arrange
repository_root = tmp_path / "repository"
repository_root.mkdir()
path_to_add = repository_root / "file.txt"
mock_latest_tag_info.return_value.repository_root = repository_root
mock_is_subpath.return_value = False
git_instance = Git(scm_config)

# Act
git_instance.add_path(path_to_add)

# Assert
mock_run_command.assert_not_called()

@patch("bumpversion.scm.git.run_command")
@patch("bumpversion.scm.git.Git.latest_tag_info")
@patch("bumpversion.scm.git.is_subpath")
def test_raises_error_on_command_failure(
self, mock_is_subpath, mock_latest_tag_info, mock_run_command, scm_config: SCMConfig, tmp_path: Path
):
"""If the git command fails, a BumpVersionError should be raised."""
# Arrange
repository_root = tmp_path / "repository"
repository_root.mkdir()
path_to_add = repository_root / "file.txt"
mock_latest_tag_info.return_value.repository_root = repository_root
mock_is_subpath.return_value = True
mock_run_command.side_effect = subprocess.CalledProcessError(returncode=1, cmd="git add")
git_instance = Git(scm_config)

# Act / Assert
with pytest.raises(BumpVersionError):
git_instance.add_path(path_to_add)


class TestRevisionInfo:
"""Tests for the revision_info function."""
Expand Down

0 comments on commit 8ad5c82

Please sign in to comment.