#!/bin/bash # Script para ejecutar clang-tidy recursivamente en todo el código fuente # Uso: # ./run_clang-tidy.sh [--fix] [--help] [archivos...] # --fix: Aplica las correcciones automáticamente (opcional) # --help: Muestra la ayuda # archivos: Archivos específicos a analizar (opcional, si no se especifica analiza todos) # Función de ayuda show_help() { cat << EOF Uso: ./run_clang-tidy.sh [OPCIONES] [ARCHIVOS...] Script para ejecutar clang-tidy en el código fuente del proyecto. OPCIONES: --fix Aplica las correcciones automáticamente --help Muestra este mensaje de ayuda ARCHIVOS: Si no se especifican archivos, se analizan todos los archivos del proyecto (excluyendo la carpeta external/). Si se especifican archivos, solo se analizan esos archivos específicos. EJEMPLOS: # Analizar todo el proyecto ./run_clang-tidy.sh # Analizar todo el proyecto y aplicar correcciones ./run_clang-tidy.sh --fix # Analizar un archivo específico ./run_clang-tidy.sh source/game/entities/enemy.cpp # Analizar múltiples archivos ./run_clang-tidy.sh source/game/entities/enemy.cpp source/game/entities/player.cpp # Analizar y corregir un archivo específico ./run_clang-tidy.sh --fix source/game/entities/enemy.cpp # Analizar todos los archivos de una carpeta (usando glob) ./run_clang-tidy.sh source/game/entities/*.cpp NOTAS: - Se requiere que el directorio build/ exista y contenga compile_commands.json - Los archivos se procesan en paralelo (4 procesos) - Solo se procesan archivos .cpp, .hpp y .h - Las rutas pueden ser relativas o absolutas EOF exit 0 } # Auto-detectar la ubicación del script y calcular rutas del proyecto SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) PROJECT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd) SOURCE_DIR="$PROJECT_DIR/source" BUILD_DIR="$PROJECT_DIR/build" # Parsear argumentos: separar --fix, --help de archivos FIX_FLAG="" FILES=() for arg in "$@"; do if [[ "$arg" == "--fix" ]]; then FIX_FLAG="--fix" elif [[ "$arg" == "--help" || "$arg" == "-h" ]]; then show_help else FILES+=("$arg") fi done # Mostrar modo if [[ -n "$FIX_FLAG" ]]; then echo "Modo: Aplicando correcciones automáticamente (--fix)" else echo "Modo: Solo análisis (sin --fix)" fi echo # Verificar que los directorios existen if [[ ! -d "$SOURCE_DIR" ]]; then echo "Error: El directorio source/ no existe en: $SOURCE_DIR" exit 1 fi if [[ ! -d "$BUILD_DIR" ]]; then echo "Error: El directorio build/ no existe en: $BUILD_DIR" echo "Ejecuta primero: cmake -B build && cmake --build build" exit 1 fi echo "Proyecto: $PROJECT_DIR" echo "Fuentes: $SOURCE_DIR" echo "Build: $BUILD_DIR" echo # Si se especificaron archivos, procesarlos directamente if [[ ${#FILES[@]} -gt 0 ]]; then echo "=== Procesando ${#FILES[@]} archivo(s) específico(s) ===" # Validar y procesar cada archivo VALID_FILES=() for file in "${FILES[@]}"; do # Convertir a ruta absoluta si es relativa if [[ ! "$file" = /* ]]; then file="$PROJECT_DIR/$file" fi # Verificar que existe if [[ ! -f "$file" ]]; then echo "Advertencia: Archivo no encontrado: $file (omitiendo)" continue fi # Verificar extensión if [[ "$file" =~ \.(cpp|hpp|h)$ ]]; then VALID_FILES+=("$file") else echo "Advertencia: Archivo no es C++: $file (omitiendo)" fi done # Si no hay archivos válidos, salir if [[ ${#VALID_FILES[@]} -eq 0 ]]; then echo "Error: No hay archivos válidos para procesar" exit 1 fi echo # Procesar archivos en paralelo printf '%s\n' "${VALID_FILES[@]}" | \ xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG" echo echo "¡Proceso completado para ${#VALID_FILES[@]} archivo(s)!" else # Comportamiento original: procesar todos los archivos echo "=== Escaneando recursivamente source/ (excluyendo external/) ===" find "$SOURCE_DIR" \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -not -path "*/external/*" -print0 | \ xargs -0 -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG" echo echo "¡Proceso completado para todos los archivos!" fi