Files
skel/.githooks/githooks.sh
David Tomaschik 3cad40f858 Add githooks.sh
2026-02-19 15:55:10 -08:00

81 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# --- 1. Identity Resolution ---
# Finds the physical location of this script, regardless of symlinks
REAL_PATH=$(realpath "$0")
REAL_NAME=$(basename "$REAL_PATH")
HOOKS_DIR=$(dirname "$REAL_PATH")
CALLED_AS=$(basename "$0")
# --- 2. Self-Installation / Sync Logic ---
if [ "$CALLED_AS" == "$REAL_NAME" ]; then
echo "🔧 Synchronizing Git Hook Dispatcher..."
# Point Git to this directory
git config core.hooksPath "$HOOKS_DIR"
# Create symlinks for any [hook-name].d directories found
for d in "$HOOKS_DIR"/*.d/; do
[ -d "$d" ] || continue
HOOK_NAME=$(basename "$d" .d)
TARGET="$HOOKS_DIR/$HOOK_NAME"
if [ ! -L "$TARGET" ]; then
ln -sf "$REAL_NAME" "$TARGET"
chmod +x "$TARGET"
echo " ✨ Linked: $HOOK_NAME"
fi
done
# Cleanup: Remove symlinks that no longer have a matching .d directory
for link in "$HOOKS_DIR"/*; do
if [ -L "$link" ] && [ "$(basename "$link")" != "$REAL_NAME" ]; then
if [ ! -d "${link}.d" ]; then
rm "$link"
echo " 🗑️ Removed: $(basename "$link")"
fi
fi
done
echo "✅ Done."
exit 0
fi
# --- 3. Selective Stdin Buffering ---
# Buffer stdin only for hooks that expect it to prevent hanging/performance hits
STDIN_DATA=""
case "$CALLED_AS" in
pre-push|post-rewrite|pre-receive|post-receive|reference-transaction)
# Check if stdin has data (is not a terminal)
if [ ! -t 0 ]; then
STDIN_DATA=$(cat)
fi
;;
esac
# --- 4. Dispatch Logic ---
SUB_HOOK_DIR="${HOOKS_DIR}/${CALLED_AS}.d"
if [ -d "$SUB_HOOK_DIR" ]; then
# Sort files naturally so 01- runs before 02-
for script in $(ls "$SUB_HOOK_DIR" | sort); do
FULL_PATH="$SUB_HOOK_DIR/$script"
[ -x "$FULL_PATH" ] || continue
# Replay stdin if we captured it, otherwise execute normally
if [ -n "$STDIN_DATA" ]; then
echo "$STDIN_DATA" | "$FULL_PATH" "$@"
else
"$FULL_PATH" "$@"
fi
# Exit immediately if any sub-script fails
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ]; then
echo "❌ Hook '$CALLED_AS' failed at: $script"
exit $EXIT_CODE
fi
done
fi
exit 0