Browse Source
Implements comprehensive pre-commit hook system to prevent debug code from reaching protected branches while maintaining developer choice. - Hooks stored in scripts/git-hooks/ (not in .git tree) - Deliberate installation required - no forced behavior - Automated installation script for team members - Comprehensive testing - Branch-aware execution (protected vs feature branches) - Configurable patterns and protected branch list Philosophy: Each developer chooses whether to use the hook, ensuring team flexibility while providing powerful debug code prevention tools.build-web-serve-test
6 changed files with 700 additions and 9 deletions
@ -0,0 +1,103 @@ |
|||
# TimeSafari Git Hooks |
|||
|
|||
This directory contains custom Git hooks for the TimeSafari project. |
|||
|
|||
## Debug Code Checker Hook |
|||
|
|||
### Overview |
|||
The `pre-commit` hook automatically checks for debug code when committing to protected branches (master, main, production, release). This prevents debug statements from accidentally reaching production code. |
|||
|
|||
### How It Works |
|||
1. **Branch Detection**: Only runs on protected branches (configurable) |
|||
2. **File Filtering**: Automatically skips test files, scripts, and documentation |
|||
3. **Pattern Matching**: Detects common debug patterns using regex |
|||
4. **Commit Prevention**: Blocks commits containing debug code |
|||
|
|||
### Protected Branches (Default) |
|||
- `master` |
|||
- `main` |
|||
- `production` |
|||
- `release` |
|||
- `stable` |
|||
|
|||
### Debug Patterns Detected |
|||
- **Console statements**: `console.log`, `console.debug`, `console.error` |
|||
- **Template debug**: `Debug:`, `debug:` in Vue templates |
|||
- **Debug constants**: `DEBUG_`, `debug_` variables |
|||
- **HTML debug**: `<!-- debug` comments |
|||
- **Debug attributes**: `debug="true"` attributes |
|||
- **Vue debug**: `v-if="debug"`, `v-show="debug"` |
|||
- **Debug TODOs**: `TODO debug`, `FIXME debug` |
|||
|
|||
### Files Automatically Skipped |
|||
- Test files: `*.test.js`, `*.spec.ts`, `*.test.vue` |
|||
- Scripts: `scripts/` directory |
|||
- Test directories: `test-*` directories |
|||
- Documentation: `docs/`, `*.md`, `*.txt` |
|||
- Config files: `*.json`, `*.yml`, `*.yaml` |
|||
- IDE files: `.cursor/` directory |
|||
|
|||
### Configuration |
|||
Edit `.git/hooks/debug-checker.config` to customize: |
|||
- Protected branches |
|||
- Debug patterns |
|||
- Skip patterns |
|||
- Logging level |
|||
|
|||
### Testing the Hook |
|||
Run the test script to verify the hook works: |
|||
```bash |
|||
./scripts/test-debug-hook.sh |
|||
``` |
|||
|
|||
### Manual Testing |
|||
1. Make changes to a file with debug code |
|||
2. Stage the file: `git add <filename>` |
|||
3. Try to commit: `git commit -m 'test'` |
|||
4. Hook should prevent commit if debug code is found |
|||
|
|||
### Bypassing the Hook (Emergency) |
|||
If you absolutely need to commit debug code to a protected branch: |
|||
```bash |
|||
git commit --no-verify -m "emergency: debug code needed" |
|||
``` |
|||
⚠️ **Warning**: This bypasses all pre-commit hooks. Use sparingly and only in emergencies. |
|||
|
|||
### Troubleshooting |
|||
|
|||
#### Hook not running |
|||
- Ensure the hook is executable: `chmod +x .git/hooks/pre-commit` |
|||
- Check if you're on a protected branch |
|||
- Verify the hook file exists and has correct permissions |
|||
|
|||
#### False positives |
|||
- Add legitimate debug patterns to skip patterns in config |
|||
- Use proper logging levels (`logger.info`, `logger.debug`) instead of console |
|||
- Move debug code to feature branches first |
|||
|
|||
#### Hook too strict |
|||
- Modify debug patterns in config file |
|||
- Add more file types to skip patterns |
|||
- Adjust protected branch list |
|||
|
|||
### Best Practices |
|||
1. **Use feature branches** for development with debug code |
|||
2. **Use proper logging** instead of console statements |
|||
3. **Test thoroughly** before merging to protected branches |
|||
4. **Review commits** to ensure no debug code slips through |
|||
5. **Keep config updated** as project needs change |
|||
|
|||
### Integration with CI/CD |
|||
This hook works locally. For CI/CD pipelines, consider: |
|||
- Running the same checks in your build process |
|||
- Adding ESLint rules for console statements |
|||
- Using TypeScript strict mode |
|||
- Adding debug code detection to PR checks |
|||
|
|||
### Support |
|||
If you encounter issues: |
|||
1. Check the hook output for specific error messages |
|||
2. Verify your branch is in the protected list |
|||
3. Review the configuration file |
|||
4. Test with the provided test script |
|||
5. Check file permissions and git setup |
@ -0,0 +1,70 @@ |
|||
# TimeSafari Debug Checker Configuration |
|||
# Edit this file to customize protected branches and debug patterns |
|||
|
|||
# Protected branches where debug code checking is enforced |
|||
# Add or remove branches as needed |
|||
PROTECTED_BRANCHES=( |
|||
"master" |
|||
"main" |
|||
"production" |
|||
"release" |
|||
"stable" |
|||
) |
|||
|
|||
# Debug patterns to detect (regex patterns) |
|||
# Add or remove patterns as needed |
|||
DEBUG_PATTERNS=( |
|||
# Console statements |
|||
"console\." |
|||
|
|||
# Template debug text |
|||
"Debug:" |
|||
"debug:" |
|||
|
|||
# Debug constants and variables |
|||
"DEBUG_" |
|||
"debug_" |
|||
|
|||
# HTML debug comments |
|||
"<!-- debug" |
|||
|
|||
# Debug attributes |
|||
"debug.*=" |
|||
|
|||
# Vue debug patterns |
|||
"v-if.*debug" |
|||
"v-show.*debug" |
|||
|
|||
# Common debug text |
|||
"TODO.*debug" |
|||
"FIXME.*debug" |
|||
|
|||
# Debug imports (uncomment if you want to catch these) |
|||
# "import.*debug" |
|||
# "require.*debug" |
|||
) |
|||
|
|||
# Files and directories to skip during checking |
|||
# Add patterns to exclude from debug checking |
|||
SKIP_PATTERNS=( |
|||
"\.(test|spec)\.(js|ts|vue)$" # Test files (must have .test. or .spec.) |
|||
"^scripts/" # Scripts directory |
|||
"^test-.*/" # Test directories (must end with /) |
|||
"^\.git/" # Git directory |
|||
"^node_modules/" # Dependencies |
|||
"^docs/" # Documentation |
|||
"^\.cursor/" # Cursor IDE files |
|||
"\.md$" # Markdown files |
|||
"\.txt$" # Text files |
|||
"\.json$" # JSON config files |
|||
"\.yml$" # YAML config files |
|||
"\.yaml$" # YAML config files |
|||
) |
|||
|
|||
# Logging level (debug, info, warn, error) |
|||
LOG_LEVEL="info" |
|||
|
|||
# Exit codes |
|||
EXIT_SUCCESS=0 |
|||
EXIT_DEBUG_FOUND=1 |
|||
EXIT_ERROR=2 |
@ -0,0 +1,213 @@ |
|||
#!/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 "$@" |
@ -0,0 +1,171 @@ |
|||
#!/bin/bash |
|||
|
|||
# TimeSafari Debug Hook Installer |
|||
# Run this script in any repository to install the debug pre-commit hook |
|||
|
|||
set -e |
|||
|
|||
# Colors for output |
|||
RED='\033[0;31m' |
|||
GREEN='\033[0;32m' |
|||
YELLOW='\033[1;33m' |
|||
BLUE='\033[0;34m' |
|||
NC='\033[0m' # No Color |
|||
|
|||
echo -e "${BLUE}🔧 TimeSafari Debug Hook Installer${NC}" |
|||
echo "=============================================" |
|||
|
|||
# Check if we're in a git repository |
|||
if ! git rev-parse --git-dir > /dev/null 2>&1; then |
|||
echo -e "${RED}❌ Error: Not in a git repository${NC}" |
|||
echo "Please run this script from within a git repository" |
|||
exit 1 |
|||
fi |
|||
|
|||
# Get repository root |
|||
REPO_ROOT=$(git rev-parse --show-toplevel) |
|||
HOOKS_DIR="$REPO_ROOT/.git/hooks" |
|||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
|||
|
|||
echo -e "${BLUE}Repository:${NC} $REPO_ROOT" |
|||
echo -e "${BLUE}Hooks directory:${NC} $HOOKS_DIR" |
|||
echo -e "${BLUE}Script directory:${NC} $SCRIPT_DIR" |
|||
|
|||
# Check if hooks directory exists |
|||
if [[ ! -d "$HOOKS_DIR" ]]; then |
|||
echo -e "${RED}❌ Error: Hooks directory not found${NC}" |
|||
echo "This repository may not be properly initialized" |
|||
exit 1 |
|||
fi |
|||
|
|||
# Check if we have the hook files in the repository |
|||
HOOK_SCRIPT="$SCRIPT_DIR/git-hooks/pre-commit" |
|||
CONFIG_FILE="$SCRIPT_DIR/git-hooks/debug-checker.config" |
|||
|
|||
if [[ ! -f "$HOOK_SCRIPT" ]]; then |
|||
echo -e "${RED}❌ Error: Pre-commit hook script not found${NC}" |
|||
echo "Expected location: $HOOK_SCRIPT" |
|||
echo "Make sure you're running this from the TimeSafari repository" |
|||
exit 1 |
|||
fi |
|||
|
|||
if [[ ! -f "$CONFIG_FILE" ]]; then |
|||
echo -e "${RED}❌ Error: Debug checker config not found${NC}" |
|||
echo "Expected location: $CONFIG_FILE" |
|||
echo "Make sure you're running this from the TimeSafari repository" |
|||
exit 1 |
|||
fi |
|||
|
|||
# Check if already installed |
|||
if [[ -f "$HOOKS_DIR/pre-commit" && -f "$HOOKS_DIR/debug-checker.config" ]]; then |
|||
echo -e "${YELLOW}⚠️ Debug hook already appears to be installed${NC}" |
|||
echo -e " Checking if update is needed..." |
|||
|
|||
# Check if files are different |
|||
if diff "$HOOK_SCRIPT" "$HOOKS_DIR/pre-commit" > /dev/null 2>&1; then |
|||
echo -e " ${GREEN}✅${NC} Hook script is up to date" |
|||
HOOK_UP_TO_DATE=true |
|||
else |
|||
echo -e " ${YELLOW}⚠️ Hook script differs - will update${NC}" |
|||
HOOK_UP_TO_DATE=false |
|||
fi |
|||
|
|||
if diff "$CONFIG_FILE" "$HOOKS_DIR/debug-checker.config" > /dev/null 2>&1; then |
|||
echo -e " ${GREEN}✅${NC} Config file is up to date" |
|||
CONFIG_UP_TO_DATE=true |
|||
else |
|||
echo -e " ${YELLOW}⚠️ Config file differs - will update${NC}" |
|||
CONFIG_UP_TO_DATE=false |
|||
fi |
|||
|
|||
if [[ "$HOOK_UP_TO_DATE" == true && "$CONFIG_UP_TO_DATE" == true ]]; then |
|||
echo -e "\n${GREEN}✅ Debug hook is already up to date!${NC}" |
|||
echo -e " No installation needed" |
|||
else |
|||
echo -e "\n${BLUE}Updating existing installation...${NC}" |
|||
fi |
|||
else |
|||
echo -e "\n${BLUE}Installing debug hook...${NC}" |
|||
fi |
|||
|
|||
# Copy/update the hook script if needed |
|||
if [[ "$HOOK_UP_TO_DATE" != true ]]; then |
|||
cp "$HOOK_SCRIPT" "$HOOKS_DIR/pre-commit" |
|||
chmod +x "$HOOKS_DIR/pre-commit" |
|||
echo -e " ${GREEN}✅${NC} Pre-commit hook installed/updated" |
|||
fi |
|||
|
|||
# Copy/update the config file if needed |
|||
if [[ "$CONFIG_UP_TO_DATE" != true ]]; then |
|||
cp "$CONFIG_FILE" "$HOOKS_DIR/debug-checker.config" |
|||
echo -e " ${GREEN}✅${NC} Configuration file installed/updated" |
|||
fi |
|||
|
|||
# Copy/update the README if needed |
|||
README_FILE="$SCRIPT_DIR/git-hooks/README.md" |
|||
if [[ -f "$README_FILE" ]]; then |
|||
if [[ ! -f "$HOOKS_DIR/README.md" ]] || ! diff "$README_FILE" "$HOOKS_DIR/README.md" > /dev/null 2>&1; then |
|||
cp "$README_FILE" "$HOOKS_DIR/README.md" |
|||
echo -e " ${GREEN}✅${NC} Documentation installed/updated" |
|||
else |
|||
echo -e " ${GREEN}✅${NC} Documentation is up to date" |
|||
fi |
|||
fi |
|||
|
|||
echo -e "\n${GREEN}🎉 Debug hook installation complete!${NC}" |
|||
|
|||
# Test the installation |
|||
echo -e "\n${BLUE}Testing installation...${NC}" |
|||
if [[ -x "$HOOKS_DIR/pre-commit" ]]; then |
|||
echo -e " ${GREEN}✅${NC} Hook is executable" |
|||
else |
|||
echo -e " ${RED}❌${NC} Hook is not executable" |
|||
fi |
|||
|
|||
if [[ -f "$HOOKS_DIR/debug-checker.config" ]]; then |
|||
echo -e " ${GREEN}✅${NC} Config file exists" |
|||
else |
|||
echo -e " ${RED}❌${NC} Config file missing" |
|||
fi |
|||
|
|||
# Show current branch status |
|||
CURRENT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "detached") |
|||
echo -e "\n${BLUE}Current branch:${NC} $CURRENT_BRANCH" |
|||
|
|||
# Check if this is a protected branch |
|||
PROTECTED_BRANCHES=("master" "main" "production" "release" "stable") |
|||
IS_PROTECTED=false |
|||
|
|||
for branch in "${PROTECTED_BRANCHES[@]}"; do |
|||
if [[ "$CURRENT_BRANCH" == "$branch" ]]; then |
|||
IS_PROTECTED=true |
|||
break |
|||
fi |
|||
done |
|||
|
|||
if [[ "$IS_PROTECTED" == true ]]; then |
|||
echo -e "${YELLOW}⚠️ You're on a protected branch ($CURRENT_BRANCH)${NC}" |
|||
echo -e " The debug hook will now run on all commits to this branch" |
|||
echo -e " Consider switching to a feature branch for development" |
|||
else |
|||
echo -e "${GREEN}✅ You're on a feature branch ($CURRENT_BRANCH)${NC}" |
|||
echo -e " The debug hook will be skipped on this branch" |
|||
echo -e " You can develop with debug code freely" |
|||
fi |
|||
|
|||
echo -e "\n${BLUE}Next steps:${NC}" |
|||
echo "1. The hook will now run automatically on protected branches" |
|||
echo "2. Test it by trying to commit a file with debug code" |
|||
echo "3. Use feature branches for development with debug code" |
|||
echo "4. Check the README.md in .git/hooks/ for more information" |
|||
|
|||
echo -e "\n${BLUE}To test the hook:${NC}" |
|||
echo "1. Create a test file with debug code (e.g., console.log('test'))" |
|||
echo "2. Stage it: git add <filename>" |
|||
echo "3. Try to commit: git commit -m 'test'" |
|||
echo "4. The hook should prevent the commit if debug code is found" |
|||
|
|||
echo -e "\n${BLUE}To uninstall:${NC}" |
|||
echo "rm $HOOKS_DIR/pre-commit" |
|||
echo "rm $HOOKS_DIR/debug-checker.config" |
|||
echo "rm $HOOKS_DIR/README.md" |
@ -0,0 +1,117 @@ |
|||
#!/bin/bash |
|||
|
|||
# Test script for the debug pre-commit hook |
|||
# This script helps verify that the hook is working correctly |
|||
|
|||
set -e |
|||
|
|||
echo "🧪 Testing TimeSafari Debug Pre-commit Hook" |
|||
echo "=============================================" |
|||
|
|||
# Colors for output |
|||
RED='\033[0;31m' |
|||
GREEN='\033[0;32m' |
|||
YELLOW='\033[1;33m' |
|||
BLUE='\033[0;34m' |
|||
NC='\033[0m' # No Color |
|||
|
|||
# Test directory |
|||
TEST_DIR="$(mktemp -d)" |
|||
echo -e "${BLUE}Created test directory: $TEST_DIR${NC}" |
|||
|
|||
# Function to cleanup |
|||
cleanup() { |
|||
echo -e "${YELLOW}Cleaning up test directory...${NC}" |
|||
rm -rf "$TEST_DIR" |
|||
} |
|||
|
|||
# Set trap to cleanup on exit |
|||
trap cleanup EXIT |
|||
|
|||
# Function to run test |
|||
run_test() { |
|||
local test_name="$1" |
|||
local test_file="$2" |
|||
local expected_exit="$3" |
|||
|
|||
echo -e "\n${BLUE}Running test: $test_name${NC}" |
|||
|
|||
# Create test file |
|||
echo "$test_file" > "$TEST_DIR/test.vue" |
|||
|
|||
# Stage the file |
|||
cd "$TEST_DIR" |
|||
git init > /dev/null 2>&1 |
|||
git add test.vue > /dev/null 2>&1 |
|||
|
|||
# Run the hook |
|||
if bash ../../.git/hooks/pre-commit > hook_output.txt 2>&1; then |
|||
exit_code=0 |
|||
else |
|||
exit_code=$? |
|||
fi |
|||
|
|||
# Check result |
|||
if [[ $exit_code -eq $expected_exit ]]; then |
|||
echo -e " ${GREEN}✅ PASS${NC} - Exit code: $exit_code (expected: $expected_exit)" |
|||
else |
|||
echo -e " ${RED}❌ FAIL${NC} - Exit code: $exit_code (expected: $expected_exit)" |
|||
echo -e " ${YELLOW}Hook output:${NC}" |
|||
cat hook_output.txt |
|||
fi |
|||
|
|||
# Cleanup git |
|||
rm -rf .git |
|||
rm -f hook_output.txt |
|||
} |
|||
|
|||
# Test cases |
|||
echo -e "\n${BLUE}Test Case 1: Clean file (should pass)${NC}" |
|||
run_test "Clean file" "// No debug code here" 0 |
|||
|
|||
echo -e "\n${BLUE}Test Case 2: Console statement (should fail)${NC}" |
|||
run_test "Console statement" "console.log('debug info')" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 3: Debug template (should fail)${NC}" |
|||
run_test "Debug template" "Debug: {{ isMapReady ? 'Map Ready' : 'Map Loading' }}" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 4: Debug constant (should fail)${NC}" |
|||
run_test "Debug constant" "const DEBUG_MODE = true" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 5: Mixed content (should fail)${NC}" |
|||
run_test "Mixed content" "// Some normal code\nconsole.debug('test')\n// More normal code" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 6: HTML debug comment (should fail)${NC}" |
|||
run_test "HTML debug comment" "<!-- debug: this is debug info -->" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 7: Debug attribute (should fail)${NC}" |
|||
run_test "Debug attribute" "<div debug='true'>content</div>" 1 |
|||
|
|||
echo -e "\n${BLUE}Test Case 8: Test file (should be skipped)${NC}" |
|||
run_test "Test file" "console.log('this should be skipped')" 0 |
|||
|
|||
# Test branch detection |
|||
echo -e "\n${BLUE}Testing branch detection...${NC}" |
|||
cd "$TEST_DIR" |
|||
git init > /dev/null 2>&1 |
|||
git checkout -b feature-branch > /dev/null 2>&1 |
|||
echo "console.log('debug')" > test.vue |
|||
git add test.vue > /dev/null 2>&1 |
|||
|
|||
if bash ../../.git/hooks/pre-commit > hook_output.txt 2>&1; then |
|||
echo -e " ${GREEN}✅ PASS${NC} - Hook skipped on feature branch" |
|||
else |
|||
echo -e " ${RED}❌ FAIL${NC} - Hook should have been skipped on feature branch" |
|||
echo -e " ${YELLOW}Hook output:${NC}" |
|||
cat hook_output.txt |
|||
fi |
|||
|
|||
rm -rf .git |
|||
rm -f hook_output.txt |
|||
|
|||
echo -e "\n${GREEN}🎉 All tests completed!${NC}" |
|||
echo -e "\n${BLUE}To test manually:${NC}" |
|||
echo "1. Make changes to a file with debug code" |
|||
echo "2. Stage the file: git add <filename>" |
|||
echo "3. Try to commit: git commit -m 'test'" |
|||
echo "4. The hook should prevent the commit if debug code is found" |
Loading…
Reference in new issue