diff --git a/lib/fontv/utilities.py b/lib/fontv/utilities.py index bd6bb7a..6375d10 100644 --- a/lib/fontv/utilities.py +++ b/lib/fontv/utilities.py @@ -10,6 +10,8 @@ import os +import git.repo.fun + def dir_exists(dirpath): """Tests for existence of a directory on the string filepath""" @@ -39,13 +41,26 @@ def get_git_root_path(filepath): :raises: IOError if unable to detect the root of the git repository through this path traversal """ + if "GIT_DIR" in os.environ: + dot_git = os.path.abspath(os.environ["GIT_DIR"]) + if git.repo.fun.is_git_dir(dot_git): + return os.path.dirname(dot_git) + # begin by defining directory that contains font as the git root needle gitroot_path = os.path.dirname(os.path.abspath(filepath)) # search up to five directories above for the git repo root for _ in range(6): - if dir_exists(os.path.join(gitroot_path, ".git")): + dot_git = os.path.join(gitroot_path, ".git") + if git.repo.fun.is_git_dir(dot_git): return gitroot_path + elif file_exists(dot_git): + # Returns something like ".../font-v/.git/worktrees/work-worktrees-work" + worktree_path = git.repo.fun.find_worktree_git_dir(dot_git) + if worktree_path: + # ".../font-v/.git/worktrees/work-worktrees-work" -> ".../font-v" + return worktree_path.split("/.git/worktrees/", 2)[0] + gitroot_path = os.path.dirname(gitroot_path) raise IOError( diff --git a/tests/test_utilities.py b/tests/test_utilities.py index 089b5e1..26448fd 100644 --- a/tests/test_utilities.py +++ b/tests/test_utilities.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import os +import subprocess import pytest @@ -56,12 +57,45 @@ def test_utilities_get_gitrootpath_function_returns_proper_path_three_levels_up( assert os.path.isdir(gitdir_path) is True +@pytest.fixture +def worktree_fixture(): + subprocess.check_call( + ["git", "worktree", "add", "--detach", "/tmp/font-v", "HEAD^"] + ) + yield + subprocess.call( + [ + "git", + "worktree", + "remove", + "/tmp/font-v", + ] + ) + + +def test_utilities_get_gitrootpath_function_returns_proper_path_from_worktree( + worktree_fixture, +): + filepath = "/tmp/font-v/README.md" + gitdir_path = get_git_root_path(filepath) + assert os.path.basename(gitdir_path) == "font-v" + assert os.path.isdir(gitdir_path) is True + + def test_utilities_get_gitrootpath_function_raises_ioerror_six_levels_up(): with pytest.raises(IOError): filepath = "tests/testfiles/deepdir/deepdir2/deepdir3/deepdir4/test.txt" get_git_root_path(filepath) +def test_utilities_get_gitrootpath_uses_git_dir_env_var(): + os.environ["GIT_DIR"] = os.path.abspath(".git") + filepath = "/this/isnt/even/a/path/but/it/doesnt/matter" + gitdir_path = get_git_root_path(filepath) + assert os.path.basename(gitdir_path) == "font-v" + assert os.path.isdir(gitdir_path) is True + + def test_utilities_is_font_ttf(): assert is_font("Test-Regular.ttf") is True