ready2merge
- voll funktionsfähige Version - kann auf GitHub hochgeladen werden
This commit is contained in:
parent
d683594d6a
commit
0652a34486
4
.gitignore
vendored
4
.gitignore
vendored
@ -12,5 +12,9 @@ target/**
|
||||
# Build - Test:
|
||||
*.txt
|
||||
|
||||
# Develop
|
||||
TODO.md
|
||||
|
||||
# Releases (realAscot)
|
||||
releases/**
|
||||
bin/**
|
||||
|
27
CHANGELOG.md
Normal file
27
CHANGELOG.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Changelog treeScanner (Rust)
|
||||
|
||||
- **2025-05-17 - v1.0.0**
|
||||
- **Geändert:**
|
||||
- [x] Komplette Neuumsetzung des TreeScanner-Tools in Rust
|
||||
- [x] Aufbau einer modularen Projektstruktur (`treebuilder.rs`, `args.rs`, `loader.rs`, `ascii_spinner.rs`, `logger.rs`)
|
||||
- [x] CLI-Parsing mit `clap` umgesetzt, inkl. Aliase und Hilfetexte
|
||||
- [x] Fortschrittsanzeige mit ASCII-Spinner als wiederverwendbares Modul integriert
|
||||
- [x] Unterstützung für `.treescanner.conf` im Home-Verzeichnis eingebaut (inkl. Auto-Erzeugung und TOML-Validierung)
|
||||
- [x] Optionale Parameter wie `--max-depth`, `--viewonly`, `--ignore`, `--align-comments` implementiert
|
||||
- [x] Fallback-Logik: CLI-Eingaben überschreiben Konfiguration bei Kollision
|
||||
- [x] Ausgabe wahlweise in Konsole oder Datei (Standard: `tree.txt`)
|
||||
- [x] Unit-Tests für Konfiguration und Kommentar-Ausrichtung hinzugefügt (`tests/config_tests.rs`)
|
||||
- [x] Fehlerausgaben für ungültige Konfiguration oder fehlende Verzeichnisse eingebaut
|
||||
- [x] Makefile mit Windows-Kompatibilität für Build + Copy-Ziel erstellt
|
||||
- [x] Icon und Metadaten in .exe eingebettet via `build.rs` und `rc.exe`
|
||||
|
||||
- **Hinzugefügt:**
|
||||
- [x] CLI-Argument `--ignore` unterstützt sowohl Kommaseparierung (CLI) als auch Listen (TOML)
|
||||
- [x] Debug- und Silent-Modus zur Steuerung der Ausgaben
|
||||
- [x] Unterstützung für Konfigurationsparameter `output`, `viewonly`, `language`, `align_comments`
|
||||
- [x] Automatische Erstellung einer gültigen Standardkonfiguration, wenn keine `.treescanner.conf` vorhanden ist
|
||||
- [x] Fehler-Feedback mit TOML-Zeilenangaben bei ungültiger Konfiguration
|
||||
|
||||
- **Entfernt:**
|
||||
- [x] Python-Version vollständig ersetzt
|
||||
- [x] Temporäre Hilfsfunktionen aus der Portierungsphase entfernt
|
91
Cargo.lock
generated
91
Cargo.lock
generated
@ -160,6 +160,22 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
@ -168,7 +184,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -215,6 +243,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
@ -251,13 +285,19 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.2.16",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
@ -271,6 +311,19 @@ dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
@ -329,6 +382,19 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.3.3",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
@ -392,12 +458,13 @@ checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
|
||||
|
||||
[[package]]
|
||||
name = "treescanner"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dirs",
|
||||
"embed-resource",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"toml",
|
||||
]
|
||||
|
||||
@ -439,6 +506,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
@ -596,3 +672,12 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "treescanner"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
edition = "2024"
|
||||
|
||||
[package.metadata.winres]
|
||||
@ -15,3 +15,5 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.8"
|
||||
dirs = "5"
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
43
Makefile
Normal file
43
Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
# =======================================
|
||||
# 🦀 Windows-kompatibles Makefile für TreeScanner
|
||||
# =======================================
|
||||
|
||||
PROJECT_NAME := treescanner
|
||||
BUILD_DIR := target/release
|
||||
OUT_DIR := bin
|
||||
|
||||
# Standardziel
|
||||
.PHONY: all
|
||||
all: build copy
|
||||
|
||||
# Release-Build
|
||||
.PHONY: build
|
||||
build:
|
||||
cargo build --release
|
||||
|
||||
# Kopiere EXE in bin\
|
||||
.PHONY: copy
|
||||
copy:
|
||||
if not exist "$(OUT_DIR)" mkdir "$(OUT_DIR)"
|
||||
copy /Y "$(BUILD_DIR)\$(PROJECT_NAME).exe" "$(OUT_DIR)\$(PROJECT_NAME).exe"
|
||||
|
||||
# Lösche alles außer bin\
|
||||
.PHONY: clean
|
||||
clean:
|
||||
cargo clean
|
||||
|
||||
# Tests
|
||||
.PHONY: test
|
||||
test:
|
||||
cargo test
|
||||
|
||||
# Lokale Installation
|
||||
.PHONY: install
|
||||
install:
|
||||
cargo install --path . --root install-local
|
||||
|
||||
# Vollständiger Reset
|
||||
.PHONY: reset
|
||||
reset: clean
|
||||
if exist "$(OUT_DIR)" rmdir /S /Q "$(OUT_DIR)"
|
||||
if exist "install-local" rmdir /S /Q "install-local"
|
175
README.md
175
README.md
@ -2,7 +2,11 @@
|
||||
|
||||

|
||||
|
||||
TreeScanner ist ein leichtgewichtiges CLI-Tool zur Darstellung von Verzeichnisstrukturen als ASCII-Baum. Dieses Tool entstand im Rahmen meines persönlichen Projekts, systemnahe Werkzeuge von C nach Rust zu migrieren.
|
||||
**TreeScanner** ist ein leichtgewichtiges, portables CLI-Tool zur rekursiven Analyse von Verzeichnisstrukturen.
|
||||
Es erzeugt eine klar strukturierte ASCII-Ausgabe und eignet sich hervorragend für Dokumentation, Debugging oder Buildsysteme.
|
||||
|
||||
> 🔧 Diese Version ist eine komplette Neuentwicklung in **Rust** und ersetzt das ursprüngliche Python-Projekt:
|
||||
> ➜ [treeScannerASCII (Python)](https://github.com/realAscot/treeScannerASCII)
|
||||
|
||||
Der original treeScanner in Python ist unter <https://github.com/realAscot/treeScannerASCII> zu finden. Dieser ist auch als Python-Modul zu verwenden.
|
||||
|
||||
@ -12,11 +16,40 @@ Der original treeScanner in Python ist unter <https://github.com/realAscot/treeS
|
||||
|
||||
- [TreeScanner CLI Verzeichnisscanner](#treescanner-cli-verzeichnisscanner)
|
||||
- [Inhalt](#inhalt)
|
||||
- [Beschreibung](#beschreibung)
|
||||
- [Installation](#installation)
|
||||
- [Über .zip Archiv](#über-zip-archiv)
|
||||
- [Installer](#installer)
|
||||
- [Struktur](#struktur)
|
||||
- [Features](#features)
|
||||
- [Verwendung](#verwendung)
|
||||
- [Beispielausgabe](#beispielausgabe)
|
||||
- [✨ Features](#-features)
|
||||
- [▶️ Verwendung](#️-verwendung)
|
||||
- [🖼 Beispielausgabe](#-beispielausgabe)
|
||||
- [⚙️ Konfiguration `.treescanner.conf`](#️-konfiguration-treescannerconf)
|
||||
- [🔍 Ort](#-ort)
|
||||
- [📘 Format](#-format)
|
||||
- [📝 Format (.toml)](#-format-toml)
|
||||
- [Lizenz](#lizenz)
|
||||
- [Eingesetzte Libraries (MIT-kompatibel):](#eingesetzte-libraries-mit-kompatibel)
|
||||
- [💬 Kontakt](#-kontakt)
|
||||
|
||||
---
|
||||
|
||||
## Beschreibung
|
||||
|
||||
Der treeScanner.exe ist ursprünglich als ein Tool entwickelt worden mit dem man Verzeichnisstrukturen für Dokumentationen erzeugen konnte.
|
||||
TreeScanner durchsucht Verzeichnisse rekursiv, filtert optional bestimmte Ordner aus und gibt eine **strukturierte ASCII-Baumdarstellung** mit Icons und optional ausgerichteten Kommentaren aus.
|
||||
Er eignet sich für technische Dokumentationen, Versionskontrollen, Release-Skripte und CI/CD-Prozesse.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### Über .zip Archiv
|
||||
|
||||
### Installer
|
||||
|
||||
Der Installer `treeScanner-Setup.exe` der jeweils die aktuelle Version auf GitHub enthällt, bietet Dir an das Programm im Windows-Verzeichnis zu installieren.
|
||||
Dies ist zwar unüblich aber
|
||||
|
||||
---
|
||||
|
||||
@ -25,37 +58,65 @@ Der original treeScanner in Python ist unter <https://github.com/realAscot/treeS
|
||||
**GEPLANTE STRUKTUR (DEV)**
|
||||
|
||||
```plaintext
|
||||
src/
|
||||
├── main.rs → CLI-Einstieg
|
||||
├── app/
|
||||
│ ├── mod.rs
|
||||
│ └── treebuilder.rs → Verzeichnisbaum erstellen
|
||||
├── config/
|
||||
│ └── args.rs → Parameterübergabe & Konfig
|
||||
├── utils/
|
||||
│ ├── ascii_spinner.rs → Fortschrittsanzeige
|
||||
│ └── logger.rs
|
||||
├── tests/ → Integrationstests
|
||||
├── media/ → Logos / Assets
|
||||
├── resources/ → .conf-Template, Icons, Versioninfo
|
||||
|
||||
📁 treeScanner #
|
||||
├── 📁 .cargo #
|
||||
│ └── 📄 config.toml #
|
||||
├── 📁 .vscode #
|
||||
│ └── 📄 tasks.json #
|
||||
├── 📁 media #
|
||||
│ ├── 📄 logo-treescanner.png #
|
||||
│ └── 📄 logo-treescanner_512x512.png #
|
||||
├── 📁 resources #
|
||||
│ ├── 📄 icon.ico #
|
||||
│ └── 📄 version.rc #
|
||||
├── 📁 src #
|
||||
│ ├── 📁 app #
|
||||
│ │ ├── 📄 mod.rs #
|
||||
│ │ └── 📄 treebuilder.rs #
|
||||
│ ├── 📁 config #
|
||||
│ │ ├── 📄 args.rs #
|
||||
│ │ ├── 📄 loader.rs #
|
||||
│ │ └── 📄 mod.rs #
|
||||
│ ├── 📁 utils #
|
||||
│ │ ├── 📄 ascii_spinner.rs #
|
||||
│ │ ├── 📄 logger.rs #
|
||||
│ │ └── 📄 mod.rs #
|
||||
│ ├── 📄 lib.rs #
|
||||
│ └── 📄 main.rs #
|
||||
├── 📁 tests #
|
||||
│ ├── 📄 config_tests.rs #
|
||||
│ └── 📄 treebuilder_tests.rs #
|
||||
├── 📄 .gitignore #
|
||||
├── 📄 build.rs #
|
||||
├── 📄 Cargo.lock #
|
||||
├── 📄 Cargo.toml #
|
||||
├── 📄 CHANGELOG.md #
|
||||
├── 📄 LICENSE #
|
||||
├── 📄 Makefile #
|
||||
├── 📄 README.md #
|
||||
└── 📄 VERSION #
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
## ✨ Features
|
||||
|
||||
- 📁 ASCII-Baumstruktur mit Icons (📁, 📄)
|
||||
- 📂 Max. Tiefe & Datei-Anzahl konfigurierbar (`--max-depth`, `--max-files-per-dir`)
|
||||
- 🚫 Ignorieren von Verzeichnissen (`--ignore .git,target`)
|
||||
- 💬 Optional ausrichtbare Kommentarspalte (`--align-comments`)
|
||||
- ⚙ Konfigurierbar per CLI oder `~/.treescanner.conf`
|
||||
- 🌀 Fortschrittsanzeige während des Scans
|
||||
- 🛠 `--quiet`, `--debug`, `--viewonly`, `--output` u. a.
|
||||
- 🧪 Tests, strukturierter Build, Markdown-fähige Ausgabe
|
||||
- 📁 ASCII-Baumdarstellung mit Icons (📁, 📄)
|
||||
- 🚫 Ignorierliste per CLI oder Konfig-Datei
|
||||
- ⏫ Limit für Tiefe (`--max-depth`) und Dateianzahl pro Verzeichnis
|
||||
- 📄 Ausgabe in Datei oder Konsole
|
||||
- ⚙ Konfigurierbar via `~/.treescanner.conf`
|
||||
- 🌀 Fortschrittsanzeige beim Scannen (Spinner)
|
||||
- 💬 Optionale Kommentarspalte (`--align-comments`)
|
||||
- 🧪 Getestete Komponenten (unit-tested)
|
||||
- 🔕 Silent-Modus (`--quiet`)
|
||||
- 🛠 Portable Binary (`.exe`) ohne externe Abhängigkeiten
|
||||
|
||||
---
|
||||
|
||||
## Verwendung
|
||||
## ▶️ Verwendung
|
||||
|
||||
```bash
|
||||
# Einfacher Scan (aktuelles Verzeichnis)
|
||||
@ -73,9 +134,10 @@ src/
|
||||
|
||||
---
|
||||
|
||||
## Beispielausgabe
|
||||
## 🖼 Beispielausgabe
|
||||
|
||||
```plaintext
|
||||
|
||||
📁 ./src/
|
||||
├── 📄 main.rs #
|
||||
├── 📁 app/ #
|
||||
@ -83,10 +145,65 @@ src/
|
||||
└── 📁 utils/ #
|
||||
├── 📄 ascii_spinner.rs #
|
||||
└── 📄 logger.rs #
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Konfiguration `.treescanner.conf`
|
||||
|
||||
### 🔍 Ort
|
||||
|
||||
Standardmäßig gesucht im **Benutzerverzeichnis**:
|
||||
|
||||
```plaintext
|
||||
Windows: C:\Users\<Benutzername>\.treescanner.conf
|
||||
Linux: /home/<user>/.treescanner.conf
|
||||
```
|
||||
|
||||
### 📘 Format
|
||||
|
||||
### 📝 Format (.toml)
|
||||
|
||||
```toml
|
||||
max_depth = 3
|
||||
max_files_per_dir = 100
|
||||
ignore = [".git", "target", ".vscode"]
|
||||
output = "tree.txt"
|
||||
viewonly = false
|
||||
align_comments = false
|
||||
```
|
||||
|
||||
- CLI-Einstellungen überschreiben Konfigurationswerte bei Kollision
|
||||
- Die Datei wird beim ersten Start automatisch erzeugt, falls sie fehlt
|
||||
- Der Pfad ist **nicht fest kodiert**, sondern dynamisch via `dirs::home_dir()` ermittelt
|
||||
|
||||
---
|
||||
|
||||
## Lizenz
|
||||
|
||||
MIT © [Adam Skotarczak](mailto:adam@skotarczak.net) siehe [LICENSE](./LICENSE)
|
||||
Dieses Projekt steht unter der [MIT-Lizenz](./LICENSE).
|
||||
|
||||
### Eingesetzte Libraries (MIT-kompatibel):
|
||||
|
||||
| Crate | Lizenz |
|
||||
|-----------------|------------|
|
||||
| `clap` | MIT/Apache |
|
||||
| `dirs` | MIT/Apache |
|
||||
| `serde` | MIT/Apache |
|
||||
| `serde_derive` | MIT/Apache |
|
||||
| `toml` | MIT/Apache |
|
||||
| `tempfile` | MIT/Apache (nur für Tests) |
|
||||
| `console` | MIT |
|
||||
|
||||
⚠️ Alle eingebundenen Libraries sind **MIT- oder Apache-2.0-kompatibel** und dürfen ohne Einschränkungen in proprietären oder Open-Source-Projekten verwendet werden.
|
||||
|
||||
siehe [LICENSE](./LICENSE)
|
||||
|
||||
---
|
||||
|
||||
## 💬 Kontakt
|
||||
|
||||
**Adam Skotarczak**
|
||||
✉ [adam@skotarczak.net](mailto:adam@skotarczak.net)
|
||||
🔗 [realAscot auf GitHub](https://github.com/realAscot)
|
||||
|
6
desktop.ini
Normal file
6
desktop.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Users\adam\Documents\Werkbank\Projekte\Projekte-Rust\treeScannerRust\resources\icon.ico,0
|
||||
[ViewState]
|
||||
Mode=
|
||||
Vid=
|
||||
FolderType=Documents
|
@ -1,7 +0,0 @@
|
||||
max_depth = 3
|
||||
max_files_per_dir = 50
|
||||
ignore = .git,__pycache__,target
|
||||
language = de
|
||||
align_comments = true
|
||||
output = tree.txt
|
||||
viewonly = false
|
@ -4,7 +4,7 @@ use std::path::PathBuf;
|
||||
/// CLI-Argumente für TreeScanner
|
||||
#[derive(Parser, Debug)]
|
||||
#[command( author ="Adam Skotarczak <adam@skotarczak.net>",
|
||||
version= "1.0.0",
|
||||
version= "0.2.0",
|
||||
about = "TreeScanner: Verzeichnisse als ASCII-Baum visualisieren.",
|
||||
|
||||
long_about = r#"
|
||||
@ -29,7 +29,7 @@ pub struct CliArgs {
|
||||
#[arg(long)]
|
||||
pub max_depth: Option<usize>,
|
||||
|
||||
/// Maximale Dateianzahl pro Verzeichnis (Standard: 100)
|
||||
/// Maximale Dateianzahl pro Verzeichnis
|
||||
#[arg(long, default_value_t = 100)]
|
||||
pub max_files_per_dir: usize,
|
||||
|
||||
@ -38,7 +38,7 @@ pub struct CliArgs {
|
||||
pub ignore: Vec<String>,
|
||||
|
||||
/// Ausgabeziel (Standard: tree.txt)
|
||||
#[arg(short, long)]
|
||||
#[arg(short = 'o', long)]
|
||||
pub output: Option<PathBuf>,
|
||||
|
||||
/// Nur in Konsole anzeigen, keine Ausgabedatei speichern
|
||||
@ -54,6 +54,6 @@ pub struct CliArgs {
|
||||
pub quiet: bool,
|
||||
|
||||
/// Kommentare ausrichten (DEV: optisch instabil)
|
||||
#[arg(long, default_value_t = false)]
|
||||
#[arg(short = 'c', long, default_value_t = false)]
|
||||
pub align_comments: bool,
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
@ -15,13 +16,72 @@ pub struct ConfigFile {
|
||||
pub viewonly: Option<bool>,
|
||||
}
|
||||
|
||||
/// Lädt die Konfigurationsdatei aus dem Home-Verzeichnis (`~/.treescanner.conf`).
|
||||
///
|
||||
/// Falls die Datei nicht existiert, wird eine gültige Standard-Konfigurationsdatei erstellt.
|
||||
/// Bei Fehlern während des Lesens oder Parsens wird `None` zurückgegeben.
|
||||
///
|
||||
/// # Rückgabewert
|
||||
/// * `Some(ConfigFile)` – wenn Datei existiert und geparst werden konnte
|
||||
/// * `None` – bei Fehlern oder wenn Datei nicht erstellt/parst werden konnte
|
||||
pub fn load_config_from_home() -> Option<ConfigFile> {
|
||||
let home = dirs::home_dir()?;
|
||||
let config_path = home.join(".treescanner.conf");
|
||||
if !config_path.exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let content = fs::read_to_string(&config_path).ok()?;
|
||||
toml::from_str(&content).ok()
|
||||
}
|
||||
// Versuche, die Datei zu lesen
|
||||
match fs::read_to_string(&config_path) {
|
||||
Ok(content) => {
|
||||
match toml::from_str::<ConfigFile>(&content) {
|
||||
Ok(cfg) => Some(cfg),
|
||||
Err(e) => {
|
||||
eprintln!("⚠️ Konfigurationsdatei ungültig (TOML-Fehler): {e}");
|
||||
println!("ℹ️ Du findest die Datei hier: {}", config_path.display());
|
||||
println!("🔁 Du kannst sie löschen, sie wird beim nächsten Start neu erstellt.");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Datei existiert nicht – erstelle neue Standard-Konfigurationsdatei
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
let default_config = r#"
|
||||
# TreeScanner Standard-Konfiguration
|
||||
# Nicht gesetzte Felder werden intern auf Defaultwerte gesetzt.
|
||||
|
||||
# max_depth = 5 # default: unendlich
|
||||
# max_files_per_dir = 1000 # default: 100
|
||||
ignore = [".git", ".fingerprint"] # default: ""
|
||||
language = "de"
|
||||
align_comments = false # default: false
|
||||
output = "treescanner.txt" # default: tree.txt
|
||||
viewonly = false # default: false
|
||||
"#;
|
||||
|
||||
let result = fs::File::create(&config_path)
|
||||
.and_then(|mut f| f.write_all(default_config.trim_start().as_bytes()));
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
println!(
|
||||
"\n✏️ Standard-Konfigurationsdatei erstellt: < {} >\n",
|
||||
config_path.display()
|
||||
);
|
||||
// Lies die frisch geschriebene Datei direkt ein
|
||||
fs::read_to_string(&config_path)
|
||||
.ok()
|
||||
.and_then(|s| toml::from_str(&s).ok())
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("⚠️ Konnte Standard-Konfigurationsdatei nicht schreiben: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Anderer Lese-Fehler (z. B. Berechtigung)
|
||||
Err(e) => {
|
||||
eprintln!("⚠️ Fehler beim Lesen der Konfigurationsdatei: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
13
src/main.rs
13
src/main.rs
@ -23,13 +23,13 @@ fn main() {
|
||||
let timer = Instant::now();
|
||||
|
||||
if !args.root_path.is_dir() {
|
||||
eprintln!("Fehler: '{}' ist kein gültiges Verzeichnis.", args.root_path.display());
|
||||
eprintln!("⚠️ Fehler: '{}' ist kein gültiges Verzeichnis.", args.root_path.display());
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
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}");
|
||||
eprintln!("⚠️ Fehler beim Erstellen des Zielordners: {e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@ -42,10 +42,11 @@ fn main() {
|
||||
} else {
|
||||
file_config.max_files_per_dir.unwrap_or(100)
|
||||
},
|
||||
ignored_dirs: if !args.ignore.is_empty() {
|
||||
args.ignore
|
||||
} else {
|
||||
file_config.ignore.unwrap_or_default().into_iter().collect()
|
||||
// Ignorierte Verzeichnisse: CLI hat Vorrang, dann Config, sonst leer
|
||||
ignored_dirs: match (!args.ignore.is_empty(), file_config.ignore) {
|
||||
(true, _) => args.ignore,
|
||||
(false, Some(set)) => set.into_iter().collect(),
|
||||
(false, None) => vec![],
|
||||
},
|
||||
folder_icon: "📁".to_string(),
|
||||
file_icon: "📄".to_string(),
|
||||
|
@ -1,6 +1,7 @@
|
||||
use treescanner::config::loader::{load_config_from_home, ConfigFile};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::fs::write;
|
||||
|
||||
fn write_temp_config(content: &str) -> PathBuf {
|
||||
let path = dirs::home_dir().unwrap().join(".treescanner.conf");
|
||||
@ -27,3 +28,27 @@ fn test_config_wird_korrekt_geladen() {
|
||||
|
||||
fs::remove_file(conf_path).ok();
|
||||
}
|
||||
|
||||
/// Test: `ignore` aus Konfigurationsdatei wird korrekt geladen
|
||||
#[test]
|
||||
fn test_ignore_from_config_file() {
|
||||
let temp_home = tempfile::tempdir().unwrap();
|
||||
let config_path = temp_home.path().join(".treescanner.conf");
|
||||
|
||||
let config_content = r#"
|
||||
ignore = [".git", "target", ".vscode"]
|
||||
"#;
|
||||
write(&config_path, config_content).expect("Konnte temporäre Config nicht schreiben.");
|
||||
|
||||
unsafe {
|
||||
std::env::set_var("HOME", temp_home.path()); // für Unix
|
||||
std::env::set_var("USERPROFILE", temp_home.path()); // für Windows
|
||||
}
|
||||
|
||||
let config = load_config_from_home().expect("Konfig konnte nicht geladen werden.");
|
||||
let ignore_set = config.ignore.expect("ignore-Feld fehlt in Config");
|
||||
|
||||
assert!(ignore_set.contains(".git"));
|
||||
assert!(ignore_set.contains("target"));
|
||||
assert!(ignore_set.contains(".vscode"));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user