#!/bin/bash # # Pre-commit hook: Verifica el formato de archivos C++ con clang-format # Los archivos en source/external/ son ignorados automáticamente # # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color # Buscar clang-format en ubicaciones comunes CLANG_FORMAT=$(command -v clang-format) if [ -z "$CLANG_FORMAT" ]; then # Buscar en ubicaciones comunes de macOS/Linux for path in \ "/opt/homebrew/opt/llvm/bin/clang-format" \ "/opt/homebrew/bin/clang-format" \ "/usr/local/opt/llvm/bin/clang-format" \ "/usr/local/bin/clang-format" \ "/usr/bin/clang-format"; do if [ -x "$path" ]; then CLANG_FORMAT="$path" break fi done fi if [ -z "$CLANG_FORMAT" ]; then echo -e "${YELLOW}Warning: clang-format not found, skipping format check${NC}" exit 0 fi # Obtener archivos staged (solo .cpp, .hpp, .h) STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(cpp|hpp|h)$') # Si no hay archivos C++ staged, salir if [ -z "$STAGED_FILES" ]; then exit 0 fi # Filtrar archivos en external/ FILES_TO_CHECK="" for file in $STAGED_FILES; do # Excluir source/external/ y archivos generados if [[ ! "$file" =~ ^source/external/ ]] && [[ ! "$file" =~ project\.h$ ]]; then if [ -f "$file" ]; then FILES_TO_CHECK="$FILES_TO_CHECK $file" fi fi done # Si no quedan archivos después del filtrado, salir if [ -z "$FILES_TO_CHECK" ]; then exit 0 fi # Verificar formato FAILED_FILES="" for file in $FILES_TO_CHECK; do if ! $CLANG_FORMAT --dry-run --Werror "$file" 2>/dev/null; then FAILED_FILES="$FAILED_FILES\n - $file" fi done # Reportar resultados if [ -n "$FAILED_FILES" ]; then echo -e "${RED}Formatting errors found in:${NC}" echo -e "$FAILED_FILES" echo "" echo -e "Run ${YELLOW}clang-format -i ${NC} to fix, or use:" echo -e " ${YELLOW}cmake --build build --target format${NC}" echo "" echo -e "To bypass this check, use: ${YELLOW}git commit --no-verify${NC}" exit 1 fi echo -e "${GREEN}Format check passed${NC}" exit 0