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.
		
		
		
		
		
			
		
			
				
					
					
						
							252 lines
						
					
					
						
							7.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							252 lines
						
					
					
						
							7.7 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.*=" | |
| ) | |
| 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 "$@"
 | |
| 
 |