diff --git a/git/util.py b/git/util.py index 2d4cc7c23..c7450b53d 100644 --- a/git/util.py +++ b/git/util.py @@ -401,7 +401,7 @@ def assure_directory_exists(path: PathLike, is_file: bool = False) -> bool: ``True`` if the directory was created, ``False`` if it already existed. """ if is_file: - path = osp.dirname(path) + path = osp.dirname(path) or osp.curdir # END handle file if not osp.isdir(path): os.makedirs(path, exist_ok=True) diff --git a/test/test_assure_directory.py b/test/test_assure_directory.py new file mode 100644 index 000000000..04de1993f --- /dev/null +++ b/test/test_assure_directory.py @@ -0,0 +1,42 @@ +from pathlib import Path + +import pytest + +from git.util import assure_directory_exists +from test.lib.fixtures import writable_fixture + + +@pytest.fixture +def directory_fixture(monkeypatch): + with writable_fixture("assure-directory.sh") as temporary: + directory = temporary.path().resolve() + with monkeypatch.context() as context: + context.chdir(directory) + yield directory + + +@pytest.mark.parametrize("path_type", [str, Path]) +def test_file_in_current_directory_already_has_parent(directory_fixture, path_type): + assert assure_directory_exists(path_type("notes.txt"), is_file=True) is False + assert not (directory_fixture / "notes.txt").exists() + + +@pytest.mark.parametrize("path_type", [str, Path]) +def test_nested_file_creates_only_missing_parent_directories(directory_fixture, path_type): + filename = path_type("new/nested/notes.txt") + assert assure_directory_exists(filename, is_file=True) is True + assert (directory_fixture / "new/nested").is_dir() + assert not (directory_fixture / "new/nested/notes.txt").exists() + assert assure_directory_exists(filename, is_file=True) is False + + +@pytest.mark.parametrize("path_type", [str, Path]) +def test_existing_directory_is_unchanged(directory_fixture, path_type): + assert assure_directory_exists(path_type("existing")) is False + + +@pytest.mark.parametrize("path_type", [str, Path]) +def test_file_cannot_be_used_as_parent_directory(directory_fixture, path_type): + with pytest.raises(FileExistsError): + assure_directory_exists(path_type("blocked/notes.txt"), is_file=True) + assert (directory_fixture / "blocked").read_text() == "occupied\n" diff --git a/tests/fixtures/assure-directory.sh b/tests/fixtures/assure-directory.sh new file mode 100644 index 000000000..438236991 --- /dev/null +++ b/tests/fixtures/assure-directory.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -eu +mkdir existing +printf 'occupied\n' > blocked