mirror of
https://github.com/Matir/skel.git
synced 2026-05-25 13:19:07 -07:00
Add githooks.sh
This commit is contained in:
80
.githooks/githooks.sh
Executable file
80
.githooks/githooks.sh
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user