#!/bin/bash # Fenrir Pre-commit Hook # # This hook validates Python syntax and basic code quality before commits. # Install with: ln -sf ../../tools/pre-commit-hook .git/hooks/pre-commit set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color echo -e "${GREEN}Fenrir Pre-commit Validation${NC}" echo "==================================" # Get the repository root REPO_ROOT=$(git rev-parse --show-toplevel) cd "$REPO_ROOT" # Track validation results VALIDATION_FAILED=0 # 1. Python Syntax Validation echo -e "\n${YELLOW}1. Validating Python syntax...${NC}" if python3 tools/validate_syntax.py --check-only; then echo -e "${GREEN}✓ Syntax validation passed${NC}" else echo -e "${RED}✗ Syntax validation failed${NC}" echo "Run: python3 tools/validate_syntax.py --fix" VALIDATION_FAILED=1 fi # 2. Check for common issues in modified files echo -e "\n${YELLOW}2. Checking modified files for common issues...${NC}" # Get list of staged Python files STAGED_PYTHON_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.py$' || true) if [ -n "$STAGED_PYTHON_FILES" ]; then ISSUES_FOUND=0 for file in $STAGED_PYTHON_FILES; do if [ -f "$file" ]; then # Check for unterminated strings (the main issue from the email) if grep -n 'f".*{$' "$file" >/dev/null 2>&1; then echo -e "${RED}✗ $file: Potential unterminated f-string${NC}" ISSUES_FOUND=1 fi # Check for missing imports that are commonly used if grep -q 'debug\.DebugLevel\.' "$file" && ! grep -q 'from.*debug' "$file" && ! grep -q 'import.*debug' "$file"; then echo -e "${YELLOW}⚠ $file: Uses debug.DebugLevel but no debug import found${NC}" fi # Check for extremely long lines (over 120 chars) that might indicate issues if awk 'length($0) > 120 {print NR ": " $0; exit 1}' "$file" >/dev/null 2>&1; then # Only warn, don't fail line_num=$(awk 'length($0) > 120 {print NR; exit}' "$file") echo -e "${YELLOW}⚠ $file:$line_num: Very long line (>120 chars)${NC}" fi fi done if [ $ISSUES_FOUND -eq 0 ]; then echo -e "${GREEN}✓ No common issues found in modified files${NC}" else echo -e "${RED}✗ Common issues found in modified files${NC}" VALIDATION_FAILED=1 fi else echo -e "${GREEN}✓ No Python files modified${NC}" fi # 3. Quick import test for core modules echo -e "\n${YELLOW}3. Testing core module imports...${NC}" IMPORT_FAILED=0 # Test core imports that are critical CORE_MODULES=( "src.fenrirscreenreader.core.fenrirManager" "src.fenrirscreenreader.core.commandManager" "src.fenrirscreenreader.core.eventManager" ) cd src for module in "${CORE_MODULES[@]}"; do if python3 -c "import $module" 2>/dev/null; then echo -e "${GREEN}✓ $module${NC}" else echo -e "${RED}✗ $module (import failed)${NC}" IMPORT_FAILED=1 fi done cd "$REPO_ROOT" if [ $IMPORT_FAILED -eq 1 ]; then echo -e "${RED}✗ Core module import test failed${NC}" VALIDATION_FAILED=1 else echo -e "${GREEN}✓ Core module imports successful${NC}" fi # 4. Check for secrets or sensitive data echo -e "\n${YELLOW}4. Checking for potential secrets...${NC}" SECRETS_FOUND=0 if [ -n "$STAGED_PYTHON_FILES" ]; then for file in $STAGED_PYTHON_FILES; do if [ -f "$file" ]; then # Check for potential passwords, keys, tokens if grep -i -E '(password|passwd|pwd|key|token|secret|api_key).*=.*["\'][^"\']{8,}["\']' "$file" >/dev/null 2>&1; then echo -e "${RED}✗ $file: Potential hardcoded secret detected${NC}" SECRETS_FOUND=1 fi fi done fi if [ $SECRETS_FOUND -eq 0 ]; then echo -e "${GREEN}✓ No potential secrets found${NC}" else echo -e "${RED}✗ Potential secrets found - please review${NC}" VALIDATION_FAILED=1 fi # Summary echo -e "\n${'='*50}" if [ $VALIDATION_FAILED -eq 0 ]; then echo -e "${GREEN}✓ All pre-commit validations passed${NC}" echo -e "${GREEN}Commit allowed to proceed${NC}" exit 0 else echo -e "${RED}✗ Pre-commit validation failed${NC}" echo -e "${RED}Commit blocked - please fix issues above${NC}" echo "" echo "Quick fixes:" echo " • Python syntax: python3 tools/validate_syntax.py --fix" echo " • Review flagged files manually" echo " • Re-run commit after fixes" exit 1 fi