feat: CLI-Verbesserungen nach detox-Analyse
- --dry-run als primäre Option (--no-changes als deprecated alias) - --special für Symlinks und Special Files - Smart Default-Excludes: .git, .svn, node_modules, .cache, __pycache__ werden automatisch ignoriert (ähnlich wie detox) - Alle Änderungen rückwärtskompatibel Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
870c49297a
commit
0972ca4d6b
2 changed files with 40 additions and 8 deletions
12
src/cli.rs
12
src/cli.rs
|
|
@ -6,7 +6,7 @@ use std::path::PathBuf;
|
||||||
#[clap(about, version, author)]
|
#[clap(about, version, author)]
|
||||||
#[clap(group(
|
#[clap(group(
|
||||||
ArgGroup::new("mode")
|
ArgGroup::new("mode")
|
||||||
.args(&["no_changes", "force"])
|
.args(&["dry_run", "force"])
|
||||||
.multiple(false)
|
.multiple(false)
|
||||||
))]
|
))]
|
||||||
pub struct Cli {
|
pub struct Cli {
|
||||||
|
|
@ -17,9 +17,9 @@ pub struct Cli {
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
pub quiet: bool,
|
pub quiet: bool,
|
||||||
|
|
||||||
/// Nur anzeigen, aber keine realen Änderungen vornehmen
|
/// Nur anzeigen, aber keine realen Änderungen vornehmen (dry-run)
|
||||||
#[clap(short, long)]
|
#[clap(short = 'n', long = "dry-run", alias = "no-changes")]
|
||||||
pub no_changes: bool,
|
pub dry_run: bool,
|
||||||
|
|
||||||
/// Existierende Dateien überschreiben
|
/// Existierende Dateien überschreiben
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
|
|
@ -36,4 +36,8 @@ pub struct Cli {
|
||||||
/// Erlaubt, auch das Wurzelverzeichnis anzupassen
|
/// Erlaubt, auch das Wurzelverzeichnis anzupassen
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub modify_root: bool,
|
pub modify_root: bool,
|
||||||
|
|
||||||
|
/// Auch symbolische Links und Special Files verarbeiten
|
||||||
|
#[clap(long)]
|
||||||
|
pub special: bool,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
src/main.rs
36
src/main.rs
|
|
@ -14,6 +14,20 @@ use sanitizer::{clean_filename, is_excluded, is_safe_rename};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
// Standard-Ausschlussmuster (ähnlich wie detox)
|
||||||
|
const DEFAULT_EXCLUDES: &[&str] = &[
|
||||||
|
".git",
|
||||||
|
".git/**",
|
||||||
|
".svn",
|
||||||
|
".svn/**",
|
||||||
|
"node_modules",
|
||||||
|
"node_modules/**",
|
||||||
|
".cache",
|
||||||
|
".cache/**",
|
||||||
|
"__pycache__",
|
||||||
|
"__pycache__/**",
|
||||||
|
];
|
||||||
|
|
||||||
/// Startpunkt des Programms
|
/// Startpunkt des Programms
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
// Initialisiere Logger
|
// Initialisiere Logger
|
||||||
|
|
@ -26,9 +40,14 @@ fn main() -> Result<()> {
|
||||||
let config = Config::from_default_locations(args.verbose)?;
|
let config = Config::from_default_locations(args.verbose)?;
|
||||||
// let config = Config::load(".NameToUnix.conf", args.verbose)?;
|
// let config = Config::load(".NameToUnix.conf", args.verbose)?;
|
||||||
|
|
||||||
// Ausschlussmuster (Glob-Patterns) vorbereiten
|
// Ausschlussmuster (Glob-Patterns) vorbereiten - Default-Excludes + User-Excludes
|
||||||
let exclude_patterns = args
|
let mut all_excludes = DEFAULT_EXCLUDES
|
||||||
.exclude
|
.iter()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
all_excludes.extend(args.exclude.clone());
|
||||||
|
|
||||||
|
let exclude_patterns = all_excludes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pattern| {
|
.map(|pattern| {
|
||||||
Pattern::new(pattern)
|
Pattern::new(pattern)
|
||||||
|
|
@ -89,6 +108,15 @@ fn main() -> Result<()> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special Files (Symlinks, etc.) nur mit --special verarbeiten
|
||||||
|
let file_type = entry.file_type();
|
||||||
|
if !args.special && (!file_type.is_file() && !file_type.is_dir()) {
|
||||||
|
if args.verbose {
|
||||||
|
debug!("Skip special file: {}", old_path.display());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Dateiname (oder Verzeichnisname) ermitteln
|
// Dateiname (oder Verzeichnisname) ermitteln
|
||||||
let filename = old_path.file_name().ok_or_else(|| {
|
let filename = old_path.file_name().ok_or_else(|| {
|
||||||
anyhow::anyhow!(
|
anyhow::anyhow!(
|
||||||
|
|
@ -105,7 +133,7 @@ fn main() -> Result<()> {
|
||||||
info!("{} -> {}", old_path.display(), new_path.display());
|
info!("{} -> {}", old_path.display(), new_path.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !args.no_changes && is_safe_rename(old_path, &new_path, args.force) {
|
if !args.dry_run && is_safe_rename(old_path, &new_path, args.force) {
|
||||||
fs::rename(old_path, &new_path).with_context(|| {
|
fs::rename(old_path, &new_path).with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
"Fehler beim Umbenennen: {} -> {}",
|
"Fehler beim Umbenennen: {} -> {}",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue