Skip to content

Commit 33c3373

Browse files
committed
test: add tests for core.hooksPath support
Add 4 tests covering the hooksPath behavior: - Absolute hooksPath: hooks in a custom absolute path are found - Relative hooksPath: resolved against working tree root - Fallback: default .git/hooks used when hooksPath not set - Missing hook: no error raised when hook doesn't exist in hooksPath All tests follow the existing test patterns and are xfail-marked for Windows environments without bash.exe. Addresses review request from maintainer (Byron).
1 parent 1622e74 commit 33c3373

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

test/test_index.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,91 @@ def test_commit_msg_hook_fail(self, rw_repo):
12421242
else:
12431243
raise AssertionError("Should have caught a HookExecutionError")
12441244

1245+
# ---- core.hooksPath tests ----
1246+
1247+
@pytest.mark.xfail(
1248+
type(_win_bash_status) is WinBashStatus.Absent,
1249+
reason="Can't run a hook on Windows without bash.exe.",
1250+
raises=HookExecutionError,
1251+
)
1252+
@pytest.mark.xfail(
1253+
type(_win_bash_status) is WinBashStatus.WslNoDistro,
1254+
reason="Currently uses the bash.exe of WSL, even with no WSL distro installed",
1255+
raises=HookExecutionError,
1256+
)
1257+
@with_rw_repo("HEAD", bare=True)
1258+
def test_run_commit_hook_respects_absolute_hooks_path(self, rw_repo):
1259+
"""Hooks in a custom absolute core.hooksPath are found and executed."""
1260+
index = rw_repo.index
1261+
custom_hooks_dir = osp.join(rw_repo.working_dir, "custom-hooks")
1262+
os.makedirs(custom_hooks_dir, exist_ok=True)
1263+
hp = osp.join(custom_hooks_dir, "fake-hook")
1264+
with open(hp, "w", encoding="utf-8") as f:
1265+
f.write("#!/bin/sh\necho 'ran custom hook' >output.txt\n")
1266+
os.chmod(hp, 0o755)
1267+
1268+
rw_repo.config_writer().set_value("core", "hooksPath", custom_hooks_dir).release()
1269+
run_commit_hook("fake-hook", index)
1270+
output = Path(rw_repo.git_dir, "output.txt").read_text(encoding="utf-8")
1271+
self.assertEqual(output, "ran custom hook\n")
1272+
1273+
@pytest.mark.xfail(
1274+
type(_win_bash_status) is WinBashStatus.Absent,
1275+
reason="Can't run a hook on Windows without bash.exe.",
1276+
raises=HookExecutionError,
1277+
)
1278+
@pytest.mark.xfail(
1279+
type(_win_bash_status) is WinBashStatus.WslNoDistro,
1280+
reason="Currently uses the bash.exe of WSL, even with no WSL distro installed",
1281+
raises=HookExecutionError,
1282+
)
1283+
@with_rw_repo("HEAD", bare=True)
1284+
def test_run_commit_hook_respects_relative_hooks_path(self, rw_repo):
1285+
"""A relative core.hooksPath is resolved against the working tree root."""
1286+
index = rw_repo.index
1287+
custom_hooks_dir = osp.join(rw_repo.working_dir, "hooks-relative")
1288+
os.makedirs(custom_hooks_dir, exist_ok=True)
1289+
hp = osp.join(custom_hooks_dir, "fake-hook")
1290+
with open(hp, "w", encoding="utf-8") as f:
1291+
f.write("#!/bin/sh\necho 'ran relative hook' >output.txt\n")
1292+
os.chmod(hp, 0o755)
1293+
1294+
rw_repo.config_writer().set_value("core", "hooksPath", "hooks-relative").release()
1295+
run_commit_hook("fake-hook", index)
1296+
output = Path(rw_repo.git_dir, "output.txt").read_text(encoding="utf-8")
1297+
self.assertEqual(output, "ran relative hook\n")
1298+
1299+
@with_rw_repo("HEAD", bare=True)
1300+
def test_run_commit_hook_falls_back_to_default_without_hooks_path(self, rw_repo):
1301+
"""When core.hooksPath is not set, the default .git/hooks path is used."""
1302+
index = rw_repo.index
1303+
_make_hook(index.repo.git_dir, "fake-hook", "echo 'ran default hook' >output.txt")
1304+
run_commit_hook("fake-hook", index)
1305+
output = Path(rw_repo.git_dir, "output.txt").read_text(encoding="utf-8")
1306+
self.assertEqual(output, "ran default hook\n")
1307+
1308+
@pytest.mark.xfail(
1309+
type(_win_bash_status) is WinBashStatus.Absent,
1310+
reason="Can't run a hook on Windows without bash.exe.",
1311+
raises=HookExecutionError,
1312+
)
1313+
@pytest.mark.xfail(
1314+
type(_win_bash_status) is WinBashStatus.WslNoDistro,
1315+
reason="Currently uses the bash.exe of WSL, even with no WSL distro installed",
1316+
raises=HookExecutionError,
1317+
)
1318+
@with_rw_repo("HEAD", bare=True)
1319+
def test_run_commit_hook_hooks_path_skips_missing_hook(self, rw_repo):
1320+
"""If a hook does not exist in core.hooksPath, no error is raised."""
1321+
index = rw_repo.index
1322+
custom_hooks_dir = osp.join(rw_repo.working_dir, "empty-hooks")
1323+
os.makedirs(custom_hooks_dir, exist_ok=True)
1324+
rw_repo.config_writer().set_value("core", "hooksPath", custom_hooks_dir).release()
1325+
# Should not raise -- the hook doesn't exist, so run_commit_hook returns silently
1326+
run_commit_hook("nonexistent-hook", index)
1327+
1328+
# ---- end core.hooksPath tests ----
1329+
12451330
@with_rw_repo("HEAD")
12461331
def test_index_add_pathlib(self, rw_repo):
12471332
git_dir = Path(rw_repo.git_dir)

0 commit comments

Comments
 (0)