Implementiere farbige Terminal-Ausgabe

- Fügt colored Crate hinzu für bessere visuelle Unterscheidung
- Grün: erfolgreiche Umbenennungen
- Gelb: Dry-run Modus
- Rot: Fehlermeldungen
- Cyan/Bold: Statistik-Zusammenfassung
- Neues --no-color Flag zum Deaktivieren
- Automatische Farberkennung via is_terminal()
- Behebt ungenutzten warn Import
- Aktualisiert Integration-Tests auf neues cargo_bin! Makro

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-02-10 13:39:30 +01:00
commit 0f61e0fbd9
5 changed files with 75 additions and 27 deletions

View file

@ -6,6 +6,7 @@ mod sanitizer;
use anyhow::{Context, Result};
use clap::Parser;
use cli::Cli;
use colored::*;
use config::Config;
use glob::Pattern;
use indicatif::{ProgressBar, ProgressStyle};
@ -13,6 +14,7 @@ use log::{debug, error, info};
use rayon::prelude::*;
use sanitizer::{clean_filename, is_excluded, is_safe_rename};
use std::fs;
use std::io::IsTerminal;
use std::path::PathBuf;
use walkdir::WalkDir;
@ -40,6 +42,11 @@ struct RenameOperation {
new_path: PathBuf,
}
/// Prüft ob farbige Ausgabe aktiviert sein soll
fn should_use_color(no_color_flag: bool) -> bool {
!no_color_flag && std::io::stdout().is_terminal()
}
/// Startpunkt des Programms
fn main() -> Result<()> {
// Initialisiere Logger
@ -48,6 +55,11 @@ fn main() -> Result<()> {
// Argumente parsen
let args = Cli::parse();
// Farben konfigurieren
if !should_use_color(args.no_color) {
colored::control::set_override(false);
}
// Optional Konfigurationsdatei laden
let config = Config::from_default_locations(args.verbose)?;
// let config = Config::load(".NameToUnix.conf", args.verbose)?;
@ -85,7 +97,7 @@ fn main() -> Result<()> {
if let Ok(entry) = entry_result {
entries.push(entry);
} else if let Err(e) = entry_result {
error!("Fehler beim Durchlaufen von {}: {}", path.display(), e);
error!("{}", format!("Fehler beim Durchlaufen von {}: {}", path.display(), e).red());
}
}
@ -175,7 +187,19 @@ fn main() -> Result<()> {
}
if !args.quiet {
info!("{} -> {}", op.old_path.display(), op.new_path.display());
if args.dry_run {
info!("{} {} {}",
op.old_path.display().to_string().dimmed(),
"->".yellow(),
op.new_path.display().to_string().yellow()
);
} else {
info!("{} {} {}",
op.old_path.display().to_string().dimmed(),
"->".green(),
op.new_path.display().to_string().green()
);
}
}
if args.verbose {
@ -187,11 +211,13 @@ fn main() -> Result<()> {
match fs::rename(&op.old_path, &op.new_path) {
Ok(_) => renamed_count += 1,
Err(e) => {
error!(
"Fehler beim Umbenennen: {} -> {}: {}",
op.old_path.display(),
op.new_path.display(),
e
error!("{}",
format!(
"Fehler beim Umbenennen: {} -> {}: {}",
op.old_path.display(),
op.new_path.display(),
e
).red()
);
skipped_count += 1;
}
@ -209,15 +235,15 @@ fn main() -> Result<()> {
// Zusammenfassung ausgeben (außer im quiet mode)
if !args.quiet {
info!("");
info!("=== Zusammenfassung für {} ===", path.display());
info!("Verarbeitete Dateien/Verzeichnisse: {}", total_processed);
info!("Umbenennungen geplant: {}", total_planned);
info!("{}", format!("=== Zusammenfassung für {} ===", path.display()).cyan().bold());
info!("Verarbeitete Dateien/Verzeichnisse: {}", total_processed.to_string().cyan());
info!("Umbenennungen geplant: {}", total_planned.to_string().cyan());
if args.dry_run {
info!("Modus: Dry-run (keine Änderungen)");
info!("Modus: {}", "Dry-run (keine Änderungen)".yellow());
} else {
info!("Erfolgreich umbenannt: {}", renamed_count);
info!("Erfolgreich umbenannt: {}", renamed_count.to_string().green().bold());
if skipped_count > 0 {
info!("Übersprungen/Fehler: {}", skipped_count);
info!("Übersprungen/Fehler: {}", skipped_count.to_string().red());
}
}
}