forked from trent_larson/crowd-funder-for-time-pwa
Add whitelist functionality to debug checker to allow intentional console statements in specific files: - Add WHITELIST_FILES configuration for platform services and utilities - Update pre-commit hook to skip console pattern checks for whitelisted files - Support regex patterns in whitelist for flexible file matching - Maintain security while allowing legitimate debug code in platform services This resolves the issue where the hook was blocking commits due to intentional console statements in whitelisted files like WebPlatformService and CapacitorPlatformService.
253 lines
7.7 KiB
Bash
Executable File
253 lines
7.7 KiB
Bash
Executable File
#!/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.*="
|
|
)
|
|
DEFAULT_WHITELIST_FILES=(
|
|
"src/services/platforms/WebPlatformService.ts"
|
|
"src/services/platforms/CapacitorPlatformService.ts"
|
|
"src/services/platforms/ElectronPlatformService.ts"
|
|
)
|
|
|
|
# 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=()
|
|
WHITELIST_FILES=()
|
|
|
|
# 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"
|
|
|
|
# Read whitelist files
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^WHITELIST_FILES=\( ]]; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^\)$ ]]; then
|
|
break
|
|
fi
|
|
if [[ "$line" =~ \"([^\"]+)\" ]]; then
|
|
WHITELIST_FILES+=("${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
|
|
|
|
if [[ ${#WHITELIST_FILES[@]} -eq 0 ]]; then
|
|
WHITELIST_FILES=("${DEFAULT_WHITELIST_FILES[@]}")
|
|
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
|
|
}
|
|
|
|
# Check if file is whitelisted for console statements
|
|
is_whitelisted_file() {
|
|
local file="$1"
|
|
for whitelisted in "${WHITELIST_FILES[@]}"; do
|
|
if [[ "$file" =~ $whitelisted ]]; 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
|
|
# Skip console pattern checks for whitelisted files
|
|
if [[ "$pattern" == "console\." ]] && is_whitelisted_file "$file"; then
|
|
continue
|
|
fi
|
|
|
|
# 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 "$@"
|