Skip to content
Merged
10 changes: 9 additions & 1 deletion .github/workflows/test-hooks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ on:

jobs:
test:
name: Test on ${{ matrix.os }}
name: Test on ${{ matrix.os }} with ${{ matrix.install-method }}
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
install-method: ['install-hooks.py', 'install-hooks.sh']
exclude:
- os: windows-latest
install-method: 'install-hooks.sh'

steps:
- name: Checkout repository
Expand Down Expand Up @@ -47,3 +53,5 @@ jobs:

- name: Run Python tests
run: python test_hooks.py
env:
INSTALL_HOOKS_METHOD: ${{ matrix.install-method }}
11 changes: 7 additions & 4 deletions scripts/install-hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import sys
import os

# Automatically detect the script directory (like the shell script does)
script_dir = os.path.dirname(os.path.abspath(__file__))

def read_file(path):
print("Reading file: " + path)
with open(path, 'r') as content_file:
Expand Down Expand Up @@ -48,9 +51,9 @@ def write_file(path, content):

print("Reading hooks...")
print()
post_checkout_commands = read_file("post-checkout")
post_merge_commands = read_file("post-merge")
pre_commit_commands = read_file("pre-commit")
post_checkout_commands = read_file(os.path.join(script_dir, "post-checkout"))
post_merge_commands = read_file(os.path.join(script_dir, "post-merge"))
pre_commit_commands = read_file(os.path.join(script_dir, "pre-commit"))
print()
print()

Expand All @@ -71,6 +74,6 @@ def write_file(path, content):

except Exception as ex:
print()
print("Error occured: " + str(ex))
print("Error occurred: " + str(ex))

input("Press any key to exit.")
77 changes: 67 additions & 10 deletions test_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,81 @@ def _install_hooks(self):
"""
Install git hooks into the test repository
Hooks will be run automatically by git

Uses the installation method specified by INSTALL_HOOKS_METHOD environment variable.
If not set, defaults to install-hooks.py.
"""
install_method = os.environ.get('INSTALL_HOOKS_METHOD', 'install-hooks.py')

# Get the scripts directory
script_dir = Path(__file__).parent / 'scripts'

# Create hooks directory if it doesn't exist
hooks_dir = os.path.join(self.repo_dir, '.git', 'hooks')
os.makedirs(hooks_dir, exist_ok=True)

# Copy hook files
hooks = ['pre-commit', 'post-checkout', 'post-merge']
for hook in hooks:
src = script_dir / hook
dst = os.path.join(hooks_dir, hook)
if src.exists():
shutil.copy2(str(src), dst)
# Make executable on Unix systems
if platform.system() != 'Windows':
os.chmod(dst, 0o755)
if install_method == 'install-hooks.sh':
# Use the shell script to install hooks
install_script = script_dir / 'install-hooks.sh'
if platform.system() == 'Windows':
# On Windows, we need bash to run the shell script
# Try Git Bash first
bash_paths = [
os.path.expandvars(r'%PROGRAMFILES%\Git\bin\bash.exe'),
os.path.expandvars(r'%PROGRAMFILES(X86)%\Git\bin\bash.exe'),
]
bash_cmd = None
for bash_path in bash_paths:
if os.path.exists(bash_path):
bash_cmd = bash_path
break

if not bash_cmd:
bash_cmd = shutil.which('bash')

if bash_cmd:
subprocess.run(
[bash_cmd, str(install_script)],
cwd=self.repo_dir,
check=True
)
else:
# Raise error if bash is not available on Windows
raise RuntimeError("Bash is required to run install-hooks.sh on Windows, but it was not found")
else:
subprocess.run(
[str(install_script)],
cwd=self.repo_dir,
check=True
)

elif install_method == 'install-hooks.py':
# Use the Python script to install hooks
install_script = script_dir / 'install-hooks.py'
# The install-hooks.py script now auto-detects its directory and can be run from anywhere.
# It still requires user input for the repo path and exit confirmation.
subprocess.run(
[sys.executable, str(install_script)],
input=self.repo_dir + '\n\n', # First for repo path, second for exit prompt
text=True,
check=True,
capture_output=True
)

# The install-hooks.py script doesn't set executable permissions
# We need to do this after installation on Unix systems
if platform.system() != 'Windows':
hooks = ['pre-commit', 'post-checkout', 'post-merge']
for hook in hooks:
hook_path = os.path.join(hooks_dir, hook)
if os.path.exists(hook_path):
os.chmod(hook_path, 0o755)

else:
# Unknown installation method
raise ValueError(f"Unknown installation method: {install_method}. "
f"Expected 'install-hooks.py' or 'install-hooks.sh'")



class TestPreCommitHook(GitHooksTestCase):
Expand Down