ready2merge

- voll funktionsfähige Version
- kann auf GitHub hochgeladen werden
This commit is contained in:
Adam Skotarczak 2025-05-17 21:02:24 +02:00
parent d683594d6a
commit 0652a34486
Signed by: realAscot
GPG Key ID: 4CB9B8D93A96A538
13 changed files with 420 additions and 57 deletions

4
.gitignore vendored
View File

@ -12,5 +12,9 @@ target/**
# Build - Test:
*.txt
# Develop
TODO.md
# Releases (realAscot)
releases/**
bin/**

27
CHANGELOG.md Normal file
View 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
View File

@ -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",
]

View File

@ -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
View 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
View File

@ -2,7 +2,11 @@
![TreeScanner-Logo](./media/logo-treescanner_512x512.png)
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)

View File

@ -1 +1 @@
0.1.0
1.0.0

6
desktop.ini Normal file
View 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

View File

@ -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

View File

@ -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,
}

View File

@ -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
}
}
}

View File

@ -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(),

View File

@ -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"));
}