|
3 | 3 | # This module is part of GitPython and is released under the
|
4 | 4 | # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/
|
5 | 5 |
|
| 6 | +import contextlib |
6 | 7 | from io import BytesIO
|
7 | 8 | import logging
|
8 | 9 | import os
|
9 | 10 | import os.path as osp
|
10 | 11 | from pathlib import Path
|
11 | 12 | import re
|
| 13 | +import shutil |
12 | 14 | from stat import S_ISLNK, ST_MODE
|
13 | 15 | import subprocess
|
14 | 16 | import tempfile
|
15 | 17 |
|
| 18 | +import ddt |
16 | 19 | import pytest
|
17 | 20 | from sumtypes import constructor, sumtype
|
18 | 21 |
|
|
36 | 39 | from git.index.typ import BaseIndexEntry, IndexEntry
|
37 | 40 | from git.index.util import TemporaryFileSwap
|
38 | 41 | from git.objects import Blob
|
39 |
| -from git.util import Actor, hex_to_bin, rmtree |
| 42 | +from git.util import Actor, cwd, hex_to_bin, rmtree |
40 | 43 | from gitdb.base import IStream
|
41 | 44 | from test.lib import TestBase, fixture, fixture_path, with_rw_directory, with_rw_repo
|
42 | 45 |
|
@@ -172,6 +175,7 @@ def _make_hook(git_dir, name, content, make_exec=True):
|
172 | 175 | return hp
|
173 | 176 |
|
174 | 177 |
|
| 178 | +@ddt.ddt |
175 | 179 | class TestIndex(TestBase):
|
176 | 180 | def __init__(self, *args):
|
177 | 181 | super().__init__(*args)
|
@@ -1012,6 +1016,37 @@ def test_run_commit_hook(self, rw_repo):
|
1012 | 1016 | output = Path(rw_repo.git_dir, "output.txt").read_text(encoding="utf-8")
|
1013 | 1017 | self.assertEqual(output, "ran fake hook\n")
|
1014 | 1018 |
|
| 1019 | + # FIXME: Figure out a way to make this test also work with Absent and WslNoDistro. |
| 1020 | + @pytest.mark.xfail( |
| 1021 | + type(_win_bash_status) is WinBashStatus.WslNoDistro, |
| 1022 | + reason="Currently uses the bash.exe of WSL, even with no WSL distro installed", |
| 1023 | + raises=HookExecutionError, |
| 1024 | + ) |
| 1025 | + @ddt.data((False,), (True,)) |
| 1026 | + @with_rw_directory |
| 1027 | + def test_hook_uses_shell_not_from_cwd(self, rw_dir, case): |
| 1028 | + (chdir_to_repo,) = case |
| 1029 | + |
| 1030 | + repo = Repo.init(rw_dir) |
| 1031 | + _make_hook(repo.git_dir, "fake-hook", "echo 'ran fake hook' >output.txt") |
| 1032 | + |
| 1033 | + if os.name == "nt": |
| 1034 | + # Copy an actual binary that is not bash. |
| 1035 | + other_exe_path = Path(os.environ["SystemRoot"], "system32", "hostname.exe") |
| 1036 | + impostor_path = Path(rw_dir, "bash.exe") |
| 1037 | + shutil.copy(other_exe_path, impostor_path) |
| 1038 | + else: |
| 1039 | + # Create a shell script that doesn't do anything. |
| 1040 | + impostor_path = Path(rw_dir, "sh") |
| 1041 | + impostor_path.write_text("#!/bin/sh\n", encoding="utf-8") |
| 1042 | + os.chmod(impostor_path, 0o755) |
| 1043 | + |
| 1044 | + with cwd(rw_dir) if chdir_to_repo else contextlib.nullcontext(): |
| 1045 | + run_commit_hook("fake-hook", repo.index) |
| 1046 | + |
| 1047 | + output = Path(rw_dir, "output.txt").read_text(encoding="utf-8") |
| 1048 | + self.assertEqual(output, "ran fake hook\n") |
| 1049 | + |
1015 | 1050 | @pytest.mark.xfail(
|
1016 | 1051 | type(_win_bash_status) is WinBashStatus.Absent,
|
1017 | 1052 | reason="Can't run a hook on Windows without bash.exe.",
|
|
0 commit comments