53 lines
1.5 KiB
Bash
Executable File
53 lines
1.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# Pre-commit hook: blocks commits that change files without a corresponding task.
|
|
# Install via: scripts/install-hooks.sh
|
|
set -e
|
|
|
|
TASKS_DIR="tasks"
|
|
|
|
# Get list of changed files (staged)
|
|
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep -v "^$TASKS_DIR/" || true)
|
|
|
|
if [ -z "$CHANGED_FILES" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Check if any task spec mentions the changed files
|
|
matches=""
|
|
for file in $CHANGED_FILES; do
|
|
basename=$(basename "$file")
|
|
# Search for the filename or path in all task SPEC.md files
|
|
if grep -q -r "$basename\|$file" "$TASKS_DIR" --include="SPEC.md" 2>/dev/null; then
|
|
matches="$matches $file"
|
|
fi
|
|
done
|
|
|
|
# Count how many changed files are matched
|
|
matched_count=$(echo "$matches" | tr ' ' '\n' | sort -u | grep -c . || true)
|
|
total_count=$(echo "$CHANGED_FILES" | grep -c . || true)
|
|
|
|
if [ "$matched_count" -ge "$total_count" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Some files lack task coverage — warn and ask
|
|
echo ""
|
|
echo "=== TASK ENFORCEMENT ==="
|
|
echo "Changed files not covered by any task in $TASKS_DIR/:"
|
|
for file in $CHANGED_FILES; do
|
|
if ! echo "$matches" | grep -q "$file"; then
|
|
echo " - $file"
|
|
fi
|
|
done
|
|
echo ""
|
|
echo "The .rules.md requires all changes to go through a task."
|
|
echo "Create a task in $TASKS_DIR/{name}/SPEC.md first,"
|
|
echo "or use 'git commit --no-verify' to bypass this check."
|
|
echo ""
|
|
read -p "Continue without a task? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Commit blocked. Create a task for your changes first."
|
|
exit 1
|
|
fi
|