Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-11-01 17:47:53 +01:00
padre b12c3ebfa1
commit 2f94307a08

Ver fichero

@@ -117,6 +117,13 @@ cleanup() {
} }
trap cleanup EXIT trap cleanup EXIT
# Mostrar configuración si el formato es text
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo "[topdir] Iniciando análisis..."
echo "[topdir] Directorio: $TARGET_DIR"
echo "[topdir] Algoritmo: $HASH_ALGO"
fi
pushd "$TARGET_DIR" >/dev/null || exit 1 pushd "$TARGET_DIR" >/dev/null || exit 1
# Definir snapshot relativo al directorio objetivo o usar el custom # Definir snapshot relativo al directorio objetivo o usar el custom
@@ -131,17 +138,27 @@ else
pushd "$TARGET_DIR" >/dev/null || exit 1 pushd "$TARGET_DIR" >/dev/null || exit 1
fi fi
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo "[topdir] Snapshot: $SNAPSHOT_FILE"
fi
# Leer patrones de exclusión desde archivo si existe # Leer patrones de exclusión desde archivo si existe
if [[ -n "$IGNORE_FILE" && -f "$IGNORE_FILE" ]]; then if [[ -n "$IGNORE_FILE" && -f "$IGNORE_FILE" ]]; then
while IFS= read -r pattern; do while IFS= read -r pattern; do
[[ -z "$pattern" || "$pattern" == \#* ]] && continue [[ -z "$pattern" || "$pattern" == \#* ]] && continue
EXCLUDE_PATTERNS+=("$pattern") EXCLUDE_PATTERNS+=("$pattern")
done < "$IGNORE_FILE" done < "$IGNORE_FILE"
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo "[topdir] Cargadas ${#EXCLUDE_PATTERNS[@]} exclusiones desde $IGNORE_FILE"
fi
elif [[ -f ".topdirignore" ]]; then elif [[ -f ".topdirignore" ]]; then
while IFS= read -r pattern; do while IFS= read -r pattern; do
[[ -z "$pattern" || "$pattern" == \#* ]] && continue [[ -z "$pattern" || "$pattern" == \#* ]] && continue
EXCLUDE_PATTERNS+=("$pattern") EXCLUDE_PATTERNS+=("$pattern")
done < ".topdirignore" done < ".topdirignore"
if [[ "$OUTPUT_FORMAT" == "text" && ${#EXCLUDE_PATTERNS[@]} -gt 0 ]]; then
echo "[topdir] Cargadas ${#EXCLUDE_PATTERNS[@]} exclusiones desde .topdirignore"
fi
fi fi
# Construir comando find con exclusiones # Construir comando find con exclusiones
@@ -171,20 +188,35 @@ for pattern in "${EXCLUDE_PATTERNS[@]}"; do
done done
# Generar nuevo snapshot: compute hash para cada archivo regular # Generar nuevo snapshot: compute hash para cada archivo regular
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo -n "[topdir] Escaneando archivos..."
fi
file_count=0
while IFS= read -r -d '' file; do while IFS= read -r -d '' file; do
"$HASH_CMD" "$file" "$HASH_CMD" "$file"
file_count=$((file_count + 1))
if [[ "$OUTPUT_FORMAT" == "text" && $((file_count % 100)) -eq 0 ]]; then
echo -ne "\r[topdir] Escaneando archivos... $file_count"
fi
done < <("${find_cmd[@]}" -print0 | sort -z) > "$TMP_NEW" done < <("${find_cmd[@]}" -print0 | sort -z) > "$TMP_NEW"
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo -e "\r[topdir] Escaneados $file_count archivos "
fi
# Si no hay snapshot previo, lo creamos y salimos # Si no hay snapshot previo, lo creamos y salimos
if [[ ! -f "$SNAPSHOT_FILE" ]]; then if [[ ! -f "$SNAPSHOT_FILE" ]]; then
mv "$TMP_NEW" "$SNAPSHOT_FILE" mv "$TMP_NEW" "$SNAPSHOT_FILE"
case "$OUTPUT_FORMAT" in case "$OUTPUT_FORMAT" in
text) text)
echo "Snapshot creado en '$SNAPSHOT_FILE' (no había ejecución previa)." echo "[topdir] ✓ Snapshot creado en '$SNAPSHOT_FILE'"
echo "[topdir] ✓ $file_count archivos registrados"
echo "[topdir] Primera ejecución completada. Ejecuta nuevamente para detectar cambios."
;; ;;
json) json)
echo '{"status":"snapshot_created","snapshot_file":"'"$SNAPSHOT_FILE"'","new":[],"modified":[],"deleted":[]}' echo '{"status":"snapshot_created","snapshot_file":"'"$SNAPSHOT_FILE"'","files_tracked":'"$file_count"',"new":[],"modified":[],"deleted":[]}'
;; ;;
csv) csv)
echo "status,path" echo "status,path"
@@ -197,6 +229,10 @@ fi
# Convertir snapshot antiguo y nuevo a formato: <path>\t<checksum> # Convertir snapshot antiguo y nuevo a formato: <path>\t<checksum>
# Convertir líneas "checksum path" a formato "path<TAB>checksum" de forma robusta # Convertir líneas "checksum path" a formato "path<TAB>checksum" de forma robusta
if [[ "$OUTPUT_FORMAT" == "text" ]]; then
echo "[topdir] Comparando con snapshot anterior..."
fi
sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$SNAPSHOT_FILE" > "$TMP_OLD" 2>/dev/null || true sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$SNAPSHOT_FILE" > "$TMP_OLD" 2>/dev/null || true
sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$TMP_NEW" > "$TMP_NEW.sorted" sed -E 's/^[[:space:]]*([0-9a-f]+)[[:space:]]+(.*)$/\2\t\1/' "$TMP_NEW" > "$TMP_NEW.sorted"
mv "$TMP_NEW.sorted" "$TMP_NEW" mv "$TMP_NEW.sorted" "$TMP_NEW"
@@ -229,29 +265,41 @@ done < "$TMP_OLD.changes"
# Mostrar informe según formato # Mostrar informe según formato
case "$OUTPUT_FORMAT" in case "$OUTPUT_FORMAT" in
text) text)
echo "Informe de comparación para: $TARGET_DIR" echo ""
echo "═══════════════════════════════════════════════════════════════"
echo " INFORME DE CAMBIOS"
echo "═══════════════════════════════════════════════════════════════"
echo "Directorio: $TARGET_DIR"
echo "Archivos escaneados: $file_count"
echo "Nuevos: ${#new_files[@]} | Modificados: ${#modified_files[@]} | Eliminados: ${#delete_files[@]}"
echo "───────────────────────────────────────────────────────────────"
echo ""
if [[ ${#new_files[@]} -eq 0 && ${#modified_files[@]} -eq 0 && ${#delete_files[@]} -eq 0 ]]; then if [[ ${#new_files[@]} -eq 0 && ${#modified_files[@]} -eq 0 && ${#delete_files[@]} -eq 0 ]]; then
echo "No se detectaron cambios desde la última ejecución." echo "No se detectaron cambios desde la última ejecución."
else else
if [[ ${#new_files[@]} -gt 0 ]]; then if [[ ${#new_files[@]} -gt 0 ]]; then
echo -e "\nNuevos archivos (${#new_files[@]}):" echo "📄 NUEVOS ARCHIVOS (${#new_files[@]}):"
for f in "${new_files[@]}"; do for f in "${new_files[@]}"; do
echo " $f" echo " + $f"
done done
echo ""
fi fi
if [[ ${#modified_files[@]} -gt 0 ]]; then if [[ ${#modified_files[@]} -gt 0 ]]; then
echo -e "\nArchivos modificados (${#modified_files[@]}):" echo "✏️ ARCHIVOS MODIFICADOS (${#modified_files[@]}):"
for f in "${modified_files[@]}"; do for f in "${modified_files[@]}"; do
echo " $f" echo " ~ $f"
done done
echo ""
fi fi
if [[ ${#delete_files[@]} -gt 0 ]]; then if [[ ${#delete_files[@]} -gt 0 ]]; then
echo -e "\nArchivos eliminados desde último snapshot (${#delete_files[@]}):" echo "🗑️ ARCHIVOS ELIMINADOS (${#delete_files[@]}):"
for f in "${delete_files[@]}"; do for f in "${delete_files[@]}"; do
echo " $f" echo " - $f"
done done
echo ""
fi fi
fi fi
echo "═══════════════════════════════════════════════════════════════"
;; ;;
json) json)
@@ -281,7 +329,8 @@ case "$OUTPUT_FORMAT" in
done done
del_json+="]" del_json+="]"
echo "{\"status\":\"ok\",\"directory\":\"$TARGET_DIR\",\"hash\":\"$HASH_ALGO\",\"new\":$new_json,\"modified\":$mod_json,\"deleted\":$del_json}" total_changes=$((${#new_files[@]} + ${#modified_files[@]} + ${#delete_files[@]}))
echo "{\"status\":\"ok\",\"directory\":\"$TARGET_DIR\",\"hash\":\"$HASH_ALGO\",\"files_scanned\":$file_count,\"total_changes\":$total_changes,\"new\":$new_json,\"modified\":$mod_json,\"deleted\":$del_json}"
;; ;;
csv) csv)