You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
6.5 KiB
213 lines
6.5 KiB
#!/bin/bash
|
|
|
|
# TimeSafari Pre-commit Hook - Debug Code Checker
|
|
# Only runs on master or specified branches to catch debug code before it reaches production
|
|
|
|
# Hook directory
|
|
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
CONFIG_FILE="$HOOK_DIR/debug-checker.config"
|
|
|
|
# Default configuration (fallback if config file is missing)
|
|
DEFAULT_PROTECTED_BRANCHES=("master" "main" "production" "release")
|
|
DEFAULT_DEBUG_PATTERNS=(
|
|
"console\."
|
|
"Debug:"
|
|
"debug:"
|
|
"DEBUG_"
|
|
"debug_"
|
|
"<!-- debug"
|
|
"debug.*="
|
|
)
|
|
|
|
# Load configuration from file if it exists
|
|
load_config() {
|
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
# Source the config file to load variables
|
|
# We'll use a safer approach by reading and parsing
|
|
PROTECTED_BRANCHES=()
|
|
DEBUG_PATTERNS=()
|
|
SKIP_PATTERNS=()
|
|
|
|
# Read protected branches
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^PROTECTED_BRANCHES=\( ]]; then
|
|
# Start reading array
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^\)$ ]]; then
|
|
break
|
|
fi
|
|
if [[ "$line" =~ \"([^\"]+)\" ]]; then
|
|
PROTECTED_BRANCHES+=("${BASH_REMATCH[1]}")
|
|
fi
|
|
done
|
|
fi
|
|
done < "$CONFIG_FILE"
|
|
|
|
# Read debug patterns
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^DEBUG_PATTERNS=\( ]]; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^\)$ ]]; then
|
|
break
|
|
fi
|
|
if [[ "$line" =~ \"([^\"]+)\" ]]; then
|
|
DEBUG_PATTERNS+=("${BASH_REMATCH[1]}")
|
|
fi
|
|
done
|
|
fi
|
|
done < "$CONFIG_FILE"
|
|
|
|
# Read skip patterns
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^SKIP_PATTERNS=\( ]]; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^\)$ ]]; then
|
|
break
|
|
fi
|
|
if [[ "$line" =~ \"([^\"]+)\" ]]; then
|
|
SKIP_PATTERNS+=("${BASH_REMATCH[1]}")
|
|
fi
|
|
done
|
|
fi
|
|
done < "$CONFIG_FILE"
|
|
fi
|
|
|
|
# Use defaults if config loading failed
|
|
if [[ ${#PROTECTED_BRANCHES[@]} -eq 0 ]]; then
|
|
PROTECTED_BRANCHES=("${DEFAULT_PROTECTED_BRANCHES[@]}")
|
|
fi
|
|
|
|
if [[ ${#DEBUG_PATTERNS[@]} -eq 0 ]]; then
|
|
DEBUG_PATTERNS=("${DEFAULT_DEBUG_PATTERNS[@]}")
|
|
fi
|
|
|
|
if [[ ${#SKIP_PATTERNS[@]} -eq 0 ]]; then
|
|
SKIP_PATTERNS=("${DEFAULT_SKIP_PATTERNS[@]}")
|
|
fi
|
|
|
|
|
|
}
|
|
|
|
# Check if current branch is protected
|
|
is_protected_branch() {
|
|
local branch="$1"
|
|
for protected in "${PROTECTED_BRANCHES[@]}"; do
|
|
if [[ "$branch" == "$protected" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Check if file should be skipped
|
|
should_skip_file() {
|
|
local file="$1"
|
|
for pattern in "${SKIP_PATTERNS[@]}"; do
|
|
if [[ "$file" =~ $pattern ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
# Load configuration
|
|
load_config
|
|
|
|
# Get current branch name
|
|
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
|
|
|
|
if [[ -z "$CURRENT_BRANCH" ]]; then
|
|
echo "⚠️ Could not determine current branch, skipping debug check"
|
|
exit 0
|
|
fi
|
|
|
|
# Check if we should run the hook
|
|
if ! is_protected_branch "$CURRENT_BRANCH"; then
|
|
echo "🔒 Pre-commit hook skipped - not on protected branch ($CURRENT_BRANCH)"
|
|
echo " Protected branches: ${PROTECTED_BRANCHES[*]}"
|
|
exit 0
|
|
fi
|
|
|
|
echo "🔍 Running debug code check on protected branch: $CURRENT_BRANCH"
|
|
echo " Using config: $CONFIG_FILE"
|
|
|
|
# Get all staged files (modified, added, copied, merged)
|
|
ALL_STAGED_FILES=$(git diff --cached --name-only)
|
|
|
|
|
|
|
|
if [ -z "$ALL_STAGED_FILES" ]; then
|
|
echo "✅ No staged files to check"
|
|
exit 0
|
|
fi
|
|
|
|
# Initialize error tracking
|
|
ERRORS_FOUND=0
|
|
ERROR_MESSAGES=()
|
|
FILES_CHECKED=0
|
|
|
|
# Check each staged file for debug patterns
|
|
for file in $ALL_STAGED_FILES; do
|
|
# Skip files that should be ignored
|
|
if should_skip_file "$file"; then
|
|
continue
|
|
fi
|
|
|
|
FILES_CHECKED=$((FILES_CHECKED + 1))
|
|
|
|
# Check for debug patterns in the file
|
|
for pattern in "${DEBUG_PATTERNS[@]}"; do
|
|
# For new files, check the file content directly
|
|
# For modified files, check the staged diff
|
|
if [[ -f "$file" ]]; then
|
|
# New file - check content directly
|
|
if grep -E "$pattern" "$file" > /dev/null; then
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
ERROR_MESSAGES+=("🚨 $file: Found debug pattern '$pattern'")
|
|
fi
|
|
else
|
|
# Modified file - check staged diff
|
|
if git diff --cached "$file" | grep -E "$pattern" > /dev/null; then
|
|
ERRORS_FOUND=$((ERRORS_FOUND + 1))
|
|
ERROR_MESSAGES+=("🚨 $file: Found debug pattern '$pattern'")
|
|
fi
|
|
fi
|
|
done
|
|
done
|
|
|
|
# Report results
|
|
if [ $ERRORS_FOUND -gt 0 ]; then
|
|
echo ""
|
|
echo "❌ Debug code detected in staged files!"
|
|
echo " Branch: $CURRENT_BRANCH"
|
|
echo " Files checked: $FILES_CHECKED"
|
|
echo " Errors found: $ERRORS_FOUND"
|
|
echo ""
|
|
for msg in "${ERROR_MESSAGES[@]}"; do
|
|
echo " $msg"
|
|
done
|
|
echo ""
|
|
echo "💡 Please remove debug code before committing to $CURRENT_BRANCH"
|
|
echo " Common debug patterns to check:"
|
|
echo " - console.log, console.debug, console.error"
|
|
echo " - Debug: or debug: in templates"
|
|
echo " - DEBUG_ constants"
|
|
echo " - HTML comments with debug"
|
|
echo ""
|
|
echo " If debug code is intentional, consider:"
|
|
echo " - Moving to a feature branch first"
|
|
echo " - Using proper logging levels (logger.info, logger.debug)"
|
|
echo " - Adding debug code to .gitignore or .debugignore"
|
|
echo ""
|
|
echo " Configuration file: $CONFIG_FILE"
|
|
exit 1
|
|
else
|
|
echo "✅ No debug code found in $FILES_CHECKED staged files"
|
|
exit 0
|
|
fi
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|
|
|