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