Files
holocron/tests/test-git-hooks-install.sh
Defame1297 ba53e6544b fix(tests): isolate test-git-hooks-install.sh from inherited GIT_* env vars
The test's own `git -C "$TEMP_REPO" init` silently re-targets an inherited
GIT_DIR instead of creating a repo in the temp dir when this test itself
runs inside a git hook (e.g. pre-push sets GIT_DIR to the invoking repo's
gitdir). Unset all GIT_* vars at the top of the script so the temp repo
fixture is actually isolated regardless of the calling context.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FNJWdVvdgvZCHi1hZGqgVQ
2026-07-05 12:52:52 +00:00

147 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Tests for the git hook install block in scripts/install.sh.
# Runs install.sh from a temp repo to avoid touching the real .git/hooks/.
set -euo pipefail
# This script may itself run inside a git hook (e.g. pre-push), which sets
# GIT_DIR/GIT_EXEC_PATH/etc. in the environment. `git init`/`git -C` below
# would silently re-target the inherited GIT_DIR instead of creating an
# isolated repo in $TEMP_REPO, so start from a clean slate.
for var in $(compgen -v | grep '^GIT_'); do unset "$var"; done
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PASS=0
FAIL=0
pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
# ---------------------------------------------------------------------------
# Temp repo setup
#
# install.sh derives REPO_ROOT from the script's own location, so copying it
# into a temp tree makes REPO_ROOT point there, not at the real checkout.
# ---------------------------------------------------------------------------
TEMP_REPO="$(mktemp -d)"
TEMP_HOME="$(mktemp -d)"
trap 'rm -rf "$TEMP_REPO" "$TEMP_HOME"' EXIT
mkdir -p "$TEMP_REPO/scripts"
git -C "$TEMP_REPO" init -q
# Minimal deploy-manifest.sh — empty deploy lists so install.sh reaches the
# hook-copy block without attempting to copy files that don't exist in the
# temp tree.
cat > "$TEMP_REPO/scripts/deploy-manifest.sh" << 'EOF'
# shellcheck disable=SC2034
DEPLOY_FILES=()
DEPLOY_EXECUTABLES=()
DEPLOY_DIRS=()
EOF
# Copy the real install.sh and git-hooks into the temp repo
cp "$REPO_ROOT/scripts/install.sh" "$TEMP_REPO/scripts/install.sh"
cp -r "$REPO_ROOT/scripts/git-hooks" "$TEMP_REPO/scripts/git-hooks"
HOOKS_SRC="$TEMP_REPO/scripts/git-hooks"
run_install() {
HOME="$TEMP_HOME" bash "$TEMP_REPO/scripts/install.sh" > /dev/null 2>&1
}
# ---------------------------------------------------------------------------
echo "--- hook install: files copied to .git/hooks/ ---"
# ---------------------------------------------------------------------------
run_install
for hook_file in "$HOOKS_SRC"/*; do
[[ -f "$hook_file" ]] || continue
hook_name="$(basename "$hook_file")"
if [[ -f "$TEMP_REPO/.git/hooks/$hook_name" ]]; then
pass "$hook_name installed to .git/hooks/"
else
fail "$hook_name missing from .git/hooks/"
fi
done
# ---------------------------------------------------------------------------
echo ""
echo "--- hook install: installed hooks are executable ---"
# ---------------------------------------------------------------------------
for hook_file in "$HOOKS_SRC"/*; do
[[ -f "$hook_file" ]] || continue
hook_name="$(basename "$hook_file")"
if [[ -x "$TEMP_REPO/.git/hooks/$hook_name" ]]; then
pass "$hook_name is executable"
else
fail "$hook_name is not executable"
fi
done
# ---------------------------------------------------------------------------
echo ""
echo "--- hook install: directories in git-hooks/ are not installed ---"
# ---------------------------------------------------------------------------
# Add a subdirectory to scripts/git-hooks/ — the install block must skip it
mkdir -p "$HOOKS_SRC/not-a-hook"
run_install
if [[ ! -e "$TEMP_REPO/.git/hooks/not-a-hook" ]]; then
pass "directories in scripts/git-hooks/ are not copied to .git/hooks/"
else
fail "a directory from scripts/git-hooks/ was incorrectly installed"
fi
rmdir "$HOOKS_SRC/not-a-hook"
# ---------------------------------------------------------------------------
echo ""
echo "--- hook install: resolves correctly when GIT_DIR is inherited (hook context) ---"
# ---------------------------------------------------------------------------
# Git sets GIT_DIR/GIT_WORK_TREE for child processes when this script itself
# runs as a hook (e.g. pre-push). Simulate that and confirm install.sh still
# resolves hooks against $TEMP_REPO, not the inherited GIT_DIR.
OTHER_REPO="$(mktemp -d)"
git -C "$OTHER_REPO" init -q
if HOME="$TEMP_HOME" GIT_DIR="$OTHER_REPO/.git" GIT_WORK_TREE="$OTHER_REPO" \
bash "$TEMP_REPO/scripts/install.sh" > /dev/null 2>&1; then
if [[ -f "$TEMP_REPO/.git/hooks/post-push" ]]; then
pass "resolves \$TEMP_REPO/.git/hooks/ even with inherited GIT_DIR"
else
fail "installed into inherited GIT_DIR instead of \$TEMP_REPO"
fi
else
fail "install.sh failed when GIT_DIR/GIT_WORK_TREE were inherited"
fi
rm -rf "$OTHER_REPO"
# ---------------------------------------------------------------------------
echo ""
echo "--- hook install: idempotent ---"
# ---------------------------------------------------------------------------
run_install
for hook_file in "$HOOKS_SRC"/*; do
[[ -f "$hook_file" ]] || continue
hook_name="$(basename "$hook_file")"
if diff -q "$hook_file" "$TEMP_REPO/.git/hooks/$hook_name" > /dev/null 2>&1; then
pass "idempotent: $hook_name content unchanged after second install"
else
fail "idempotent: $hook_name content corrupted after second install"
fi
if [[ -x "$TEMP_REPO/.git/hooks/$hook_name" ]]; then
pass "idempotent: $hook_name still executable after second install"
else
fail "idempotent: $hook_name lost executable bit after second install"
fi
done
# ---------------------------------------------------------------------------
echo ""
echo "Results: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]]