optimierung-v1.1.0-prerelease

This commit is contained in:
Adam Skotarczak 2025-05-24 12:28:05 +02:00
parent f80f6ac707
commit 1e52d11971
Signed by: realAscot
GPG Key ID: 4CB9B8D93A96A538
5 changed files with 76 additions and 24 deletions

2
Cargo.lock generated
View File

@ -458,7 +458,7 @@ checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]]
name = "treescanner"
version = "1.0.1"
version = "1.1.0"
dependencies = [
"clap",
"dirs",

View File

@ -1,7 +1,9 @@
[package]
name = "treescanner"
version = "1.0.1"
edition = "2024"
version = "1.1.0" # Buildversion
edition = "2024" # Sprach­standard von Crate
#author wird in args.rs gesetzt
documentation = "https://github.com/realAscot/treeScanner/blob/main/README.md"
[package.metadata.winres]
subsystem = "console"
@ -10,7 +12,7 @@ subsystem = "console"
embed-resource = "2.4"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
clap = { version = "4.5", features = ["derive", "cargo"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.8"
dirs = "5"

View File

@ -183,6 +183,11 @@ align_comments = false
## Build
Du benötigst zum selbst kompilieren eine funktionierende Toolchain.
Das Makefile steht Dir als anhalt zur Verfügung.
1. npm installieren ->
---
## Lizenz

View File

@ -3,22 +3,33 @@ use std::path::PathBuf;
/// CLI-Argumente für TreeScanner
#[derive(Parser, Debug)]
#[command( author ="Adam Skotarczak <adam@skotarczak.net>",
version= "0.2.0",
#[command( author = "Adam Skotarczak <adam@skotarczak.net>",
// holt sich Version aus der Cargo.toml
version,
about = "TreeScanner: Verzeichnisse als ASCII-Baum visualisieren.",
long_about = r#"
TreeScanner ist ein leichtgewichtiges CLI-Tool zur strukturierten Darstellung von Verzeichnisinhalten.
Dokumentation [DE]: https://github.com/realAscot/treeScanner/blob/main/README.md
Funktionen:
- Ausgabe als ASCII-Baum
- Ausgabe als ASCII-Baum mit
- Optionen für Tiefe, Datei-Limit und Ignorierlisten
- Fortschrittsanzeige im Terminal
- Unterstützung für Konfigurationsdateien und CLI
Beispiel:
treescanner.exe --max-depth 3 --ignore .git,target
"#
"#,
// hier stellen wir das alte Format wieder her:
help_template = "\
{name} {version}
{author-section}{about-section}
USAGE:
{usage}
ARGS:
{all-args}{after-help}"
)]
pub struct CliArgs {
/// Root-Verzeichnis für den Scan (Standard: aktuelles Verzeichnis)
@ -26,11 +37,11 @@ pub struct CliArgs {
pub root_path: PathBuf,
/// Maximale Scan-Tiefe
#[arg(long)]
#[arg(short = 'f', long)]
pub max_depth: Option<usize>,
/// Maximale Dateianzahl pro Verzeichnis
#[arg(long, default_value_t = 100)]
#[arg(short = 'e', long, default_value_t = 100)]
pub max_files_per_dir: usize,
/// Verzeichnisse ignorieren (z.B. .git,target) durch Komma getrennt, ohne Leerzeichen.

View File

@ -1,22 +1,31 @@
mod config;
mod app;
mod utils;
//! Ein kleines CLI-Tool, das ein Verzeichnis einliest und
//! eine ASCII-Baumstruktur ausgibt.
//! (C) 2025 - Adam Skotarczak <adam@skotarczak.net>
mod config; // Enthält CLI-Argument-Parsing und Konfigurations-Loader
mod app; // Business-Logik: TreeBuilder
mod utils; // Hilfsfunktionen: Spinner, Logger, …
use app::treebuilder::{TreeBuilder, TreeBuilderConfig};
use config::args::CliArgs;
use config::loader::load_config_from_home;
use utils::ascii_spinner::start_spinner;
use clap::Parser;
use config::args::CliArgs; // Definition der CLI-Argumente
use config::loader::load_config_from_home; // Lädt optionale Datei-Konfiguration
use utils::ascii_spinner::start_spinner; // Zeigt einen Lade-Spinner
use clap::Parser; // CLI-Parsing mit Clap
use std::fs;
use std::time::Instant;
use utils::logger::init_logger;
use utils::logger::init_logger; // Initialisiert den Logger
/// Gibt die verstrichene Zeit seit `timer` aus.
fn view_timer(timer: &Instant) {
// `elapsed()` liefert eine Duration, hier formatiert mit (2) Nachkommastellen
println!("\n⏱️ Gesamtlaufzeit des Scans: {:.2?}", timer.elapsed());
}
// Hilfsfunktion zur Pfad-Normalisierung
/// Normalisiert einen Pfad-Eintrag für `--ignore`,
/// entfernt führende "./" bzw. ".\" und schließende Slashes.
fn normalize_ignore_entry(s: &str) -> String {
s.trim_start_matches("./")
.trim_start_matches(".\\")
@ -25,17 +34,29 @@ fn normalize_ignore_entry(s: &str) -> String {
.to_string()
}
fn main() {
// 1. Logger konfigurieren (z.B. env_logger)
init_logger();
// 2. CLI-Argumente parsen: root_path, output, ignore, etc
let args = CliArgs::parse();
// 3. Optional: Konfigurationsdatei aus ~/.config/... laden
let file_config = load_config_from_home().unwrap_or_default();
// 4. Timer starten, um Laufzeit zu messen
let timer = Instant::now();
// 5. Validierung: root_path muss ein Verzeichnis sein
if !args.root_path.is_dir() {
eprintln!("⚠️ Fehler: '{}' ist kein gültiges Verzeichnis.", args.root_path.display());
std::process::exit(1);
}
// 6. Falls ein Ausgabepfad angegeben ist, erstelle ggf. das Elternverzeichnis
if let Some(parent) = args.output.as_ref().and_then(|p| p.parent()) {
if let Err(e) = fs::create_dir_all(parent) {
eprintln!("⚠️ Fehler beim Erstellen des Zielordners: {e}");
@ -43,28 +64,34 @@ fn main() {
}
}
// 7. Ignored-Dirs: CLI hat Vorrang, sonst Datei-Konfig, sonst leer
let ignored_dirs: Vec<String> = match (!args.ignore.is_empty(), file_config.ignore) {
(true, _) => args.ignore.iter().map(|s| normalize_ignore_entry(s)).collect(),
(false, Some(set)) => set.into_iter().map(|s| normalize_ignore_entry(&s)).collect(),
(false, None) => vec![],
};
// 8. TreeBuilder-Konfiguration zusammenstellen
let config = TreeBuilderConfig {
root_path: args.root_path.clone(),
max_depth: args.max_depth.or(file_config.max_depth),
max_depth: args.max_depth.or(file_config.max_depth), // CLI oder Datei
max_files_per_dir: if args.max_files_per_dir != 100 {
args.max_files_per_dir
args.max_files_per_dir // CLI-Wert, wenn abweichend
} else {
file_config.max_files_per_dir.unwrap_or(100)
file_config.max_files_per_dir.unwrap_or(100) // sonst Datei oder Default
},
ignored_dirs,
folder_icon: "📁".to_string(),
file_icon: "📄".to_string(),
folder_icon: "📁".to_string(), // Alt: ▭
file_icon: "📄".to_string(), // Alt: 
align_comments: args.align_comments,
};
// 9. TreeBuilder initialisieren
let mut builder = TreeBuilder::new(config);
// 10. Optional: Spinner starten, wenn nicht `--quiet
let (stop_spinner, spinner_handle) = if !args.quiet {
let (s, h) = start_spinner(8);
(Some(s), Some(h))
@ -72,13 +99,16 @@ fn main() {
(None, None)
};
// 11. Baumstruktur bauen und zu einem String zusammenfügen
let mut output = builder.build_tree().join("\n");
// 12. Kommentare in den Zeilen ausrichten (wenn gewünscht)
if builder.config.align_comments {
let lines = output.lines().map(String::from).collect::<Vec<_>>();
output = builder.align_lines_with_comments(&lines).join("\n");
}
// 13. Spinner stoppen und Thread beenden
if let Some(stop) = stop_spinner {
let _ = stop.send(());
}
@ -86,15 +116,18 @@ fn main() {
let _ = handle.join();
}
// 14. Ausgabemodus: in Datei schreiben oder nur anzeigen
let viewonly = args.viewonly || file_config.viewonly.unwrap_or(false);
let output_path = args.output.clone().or_else(|| file_config.output.map(Into::into)).unwrap_or_else(|| "tree.txt".into());
if !viewonly {
// 15a. Schreibe Ergebnis in Datei
if let Err(e) = fs::write(&output_path, &output) {
eprintln!("Fehler beim Schreiben der Datei: {e}");
std::process::exit(1);
}
if !args.quiet {
// 16a. Statistik ausgeben
let (folders, files) = builder.stats();
println!(
"Erfasst wurden {} Ordner und {} Dateien. Ergebnis in {} gespeichert.",
@ -105,6 +138,7 @@ fn main() {
view_timer(&timer);
}
} else {
// 15b. Nur auf stdout ausgeben
println!("{}", output);
view_timer(&timer);
}