No description
  • Rust 74%
  • JavaScript 13.7%
  • HTML 5%
  • CSS 4%
  • Shell 2.4%
  • Other 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
wuast94 c2d9392837
Some checks failed
Release / Check if release needed (push) Successful in 5s
Release / Publish (push) Failing after 46s
Release / Release (push) Has been skipped
Merge pull request 'chore: update rust dependencies (1.53.3 → 1.54.0)' (#23) from updatarr/rust-dependencies-17605dfeaf into main
2026-10-20 07:09:17 +02:00
.cargo perf: buffer Linux links in RAM and reduce test debug data 2026-10-14 22:25:13 +02:00
.forgejo/workflows feat(ci): separate PR verification from release publication 2026-10-16 19:44:04 +02:00
.githooks fix(tooling): skip compile checks for staged documentation 2026-10-08 08:56:30 +02:00
crates chore: update rust dependencies (1.53.3 → 1.54.0) 2026-10-20 05:50:54 +02:00
docs perf: buffer Linux links in RAM and reduce test debug data 2026-10-14 22:25:13 +02:00
scripts feat(ui): add opt-in live accessible tooltips 2026-10-11 23:47:19 +02:00
.gitignore feat: initialize wuast-crates workspace with wuast-ui and wuast-common 2026-10-01 01:17:40 +02:00
.updatarr.yaml ci: implement standard rust toolchain, githooks, git-cliff and forgejo release workflows 2026-10-01 02:20:19 +02:00
AGENTS.md docs: distinguish processing capacity from HTTP admission [skip ci] 2026-10-11 14:03:45 +02:00
bacon.toml feat: initialize wuast-crates workspace with wuast-ui and wuast-common 2026-10-01 01:17:40 +02:00
Cargo.toml perf: buffer Linux links in RAM and reduce test debug data 2026-10-14 22:25:13 +02:00
CLAUDE.md feat: initialize wuast-crates workspace with wuast-ui and wuast-common 2026-10-01 01:17:40 +02:00
cliff.toml feat: decouple crate releases with independent versions and prefix tags 2026-10-01 09:57:05 +02:00
deny.toml feat(ui): add download view, calendar list, sparkline graphs, toast timer bar and fira code 2026-10-01 01:48:00 +02:00
GEMINI.md feat: initialize wuast-crates workspace with wuast-ui and wuast-common 2026-10-01 01:17:40 +02:00
Justfile fix(ci): keep verification in job logs and make coverage explicit 2026-10-09 13:01:42 +02:00
README.md fix(ci): keep verification in job logs and make coverage explicit 2026-10-09 13:01:42 +02:00
rust-toolchain.toml chore: update rust toolchain (1.99.0 → 1.99.1) 2026-10-16 21:22:04 +02:00

wuast-crates

Das zentrale Monorepo für alle geteilten Rust-Bibliotheken der wuast Homelab-Infrastruktur.

Alle Crates in diesem Workspace werden automatisch über Forgejo CI auf der privaten Registry crates.wuastbude.de (Kellnr) veröffentlicht.


📦 Enthaltene Crates

1. wuast-ui

Standardisierte UI-Komponenten, eingebettete Dracula-Theme-Assets und Axum-Router-Integration.

  • Dracula CSS: Vollständiges Farbschema, Buttons, Forms, Tabellen, Badges, Cards, Modals.
  • Embedded Assets: DraculaAssets lädt statische Dateien zur Compile-Zeit per rust-embed.
  • Axum Router: wuast_ui::assets_router() liefert /dracula.css mit 1-Zeiler aus.
  • HTML Shell: wuast_ui::dracula_shell(title, body).

2. wuast-common

Das Service-Chassis für Backend-Dienste:

  • telemetry: init("service-name") für einheitliches Tracing / Logging.
  • shutdown: ShutdownManager für SIGINT/SIGTERM, Cancellation-Tokens und begrenztes Draining über run(work).
  • health: health_router() mit standardisierten /healthz und /ready Endpunkten. health::liveness kann mit get(liveness) zusätzlich auf bestehende appbezogene Alias-Routen gelegt werden; der Standard-Router bleibt unverändert.
  • config: env_value / read_value für typisierte Konfiguration; Defaults gelten nur für fehlende Werte.
  • problems: ProblemDetails erzeugt RFC-9457-Antworten mit application/problem+json.
  • auth: AutheliaUser Axum-Extractor zum Auslesen der Authelia Proxy-Header.
  • observability (opt-in): gemeinsame HTTP-/Job-Metriken und Request-/Job-Korrelation; Vertrag.
  • workers (opt-in): beaufsichtigte langlebige Worker, sichere begrenzte Retries und seriell laufende Jobs; Vertrag.
  • http-drain (opt-in): besitzt akzeptierte Handler und ursprüngliche Response-Bodies, beendet und joint sie vor Ressourcenabbau; Vertrag.

🛠️ Entwicklung & Verifikation

Es gibt genau einen Master-Befehl für die Verifikation:

just gate

Dieser Befehl führt Formatierungsprüfung, striktes Clippy (-D warnings), alle Tests, Sicherheitschecks (cargo-deny) und Dependency-Bereinigung (cargo-machete) aus.

just test, just gate und CI führen alle realen Workspace-/Feature-Tests ohne Coverage-Instrumentierung aus. Coverage-Builds bleiben getrennt unter target/coverage-build. just coverage ist eine separate Entwicklungsprüfung mit dem vorhandenen gepinnten cargo-llvm-cov; lokale Einrichtung über just setup. Die Messung nutzt dieselben echten Szenarien einschließlich Common-Features ohne Defaults.

Vor der Instrumentierung bewahrt der Runner den öffentlichen RUSTC_WRAPPER in WUAST_COVERAGE_ORIGINAL_RUSTC_WRAPPER. Ein ursprünglich ungesetzter Wrapper lässt auch den Snapshot ungesetzt; leere und gesetzte Werte werden exakt exportiert. Native Child-Builds können damit nach Entfernen der Coverage-Flags den ursprünglichen Compiler-Cache verwenden; native Aufrufe außerhalb Coverage behalten ihre Cargo-Konfiguration ohne eigene pauschale Kompilierungsfrist. Lokale Tool- und Testprozesse werden bis zu ihrem tatsächlichen Ergebnis abgewartet; belegte Spezifikations-/Library-Defaults und notwendige eigene Laufzeit-/Testbeobachtungsgrenzen folgen der Timeout-Regel.

just coverage zeigt Zusammenfassung und fehlende Zeilen ausschließlich im Terminal; just coverage html erzeugt HTML unter target/coverage/html/ nur auf ausdrücklichen Bedarf. Keine LCOV-/JSON-/Summary-Dateien, Forgejo-Reportuploads/-downloads/-vergleiche, Screenshots oder Diagnosearchive. Browser-Tests prüfen Interaktionen, DOM und Zustände programmatisch und melden Fehler direkt im CI-Log. Stable misst Zeilen/Regionen/Funktionen; keine unbelegte Branch-Quote oder Coveragepadding. Messverfahren.

Im Hintergrund kann zur Live-Entwicklung bacon genutzt werden:

just watch

Zuständigkeit und Lifecycle

Gemeinsame Infrastruktur- und UI-Änderungen werden in diesem Repository vorgenommen. Services konsumieren veröffentlichte Kellnr-Versionen; sie enthalten ausschließlich ihre Domain-Logik und Router-Konfiguration. Neue APIs bleiben abwärtskompatibel und werden durch Feature-Flags gesteuert.

rust-template ist der verbindliche App-Grundstandard einschließlich CI, Tooling, Justfile und Agenten-Regeln. wuast-ui ist der Baukasten für frei zusammengestellte App-Oberflächen mit gemeinsamem Grundstil. Komponenten bieten benötigte Schriftgrößen, semantische Farben, Größen und Dichte über dokumentierte Optionen, Varianten oder Tokens. Gemeinsame Defaults für Rundungen, Theme, Typografie und Spacing bleiben hier, damit Apps zentrale Styling-Updates beim nächsten Library-Update übernehmen. Fehlende Bausteine/Optionen werden hier kompatibel ergänzt und vor der App-Nutzung veröffentlicht. Potenziell inkompatible Änderungen müssen vor der Umsetzung ausdrücklich vom User entschieden werden. AGENTS, CLAUDE und GEMINI enthalten denselben vollständigen Regelsatz.

use std::future::IntoFuture;
use axum::{http::StatusCode, middleware, response::IntoResponse};
use wuast_common::{
    health::HealthHandle,
    http_drain::{HttpResponses, HttpSupervisor, own},
    problems::ProblemDetails,
    shutdown::ShutdownManager,
};

# async fn example() -> Result<(), Box<dyn std::error::Error>> {
let shutdown = ShutdownManager::new();
let health = HealthHandle::ready();
let metrics = wuast_common::observability::Metrics::default();
let listener = tokio::net::TcpListener::bind("127.0.0.1:8080").await?;
let (http, requests) = HttpSupervisor::new(shutdown.clone(), HttpResponses {
    panic: || ProblemDetails::new(StatusCode::INTERNAL_SERVER_ERROR, "Request failed").into_response(),
    unavailable: || ProblemDetails::new(StatusCode::SERVICE_UNAVAILABLE, "Service is shutting down").into_response(),
});
let app = metrics.instrument_router(wuast_common::health_router_with_handle(health.clone()))
    .layer(middleware::from_fn_with_state(requests.with_metrics(metrics), own));
let signal = shutdown.clone();
let server = axum::serve(listener, app).with_graceful_shutdown(async move {
    signal.wait().await;
    health.begin_shutdown();
});
http.run(server.into_future()).await?;
# Ok(())
# }

Das Beispiel aktiviert http-drain und observability zusätzlich zu den Default-Features. with_metrics erhält dieselbe Registry wie der Router und zählt auch die endgültigen HTTP500-/HTTP503-Antworten genau einmal. wait() meldet Signale und cancelt Tokens. HttpSupervisor::run drainiert die akzeptierte Verarbeitung und abortet/joint sie bei Timeout, bevor die App Verbindungen schließt. ShutdownManager::run(work) bleibt für andere Futures unverändert verfügbar; das Droppen der äußeren Axum-Future allein beendet intern gestartete HTTP-Verarbeitung nicht.

Logging wählt automatisch Pretty für TTY und JSON für Pipes/Container. LOG_FORMAT=json bzw. LOG_FORMAT=pretty überschreibt die Auswahl. HTTP-Request- und Latenz-Logs von tower_http sind mit LOG_LEVEL=debug sichtbar; RUST_LOG erlaubt individuelle Filter.

Apps mit Worker-Supervision übernehmen das panic = "unwind"-Release-Profil der Referenz. abort beendet den Prozess unmittelbar und verhindert Panic-Supervision und kooperatives Draining. Native Release-Canary-Tests im Template sichern beide Kritikalitäten ab.

Lokale Build-Ausgaben aufräumen

Pushes über just push [Git-Argumente...] ausführen, beispielsweise just push origin main. Erst nach erfolgreichem tatsächlichem Push leert Cargo das repo-eigene target/, einschließlich Coverage-/Browser-Ausgaben. Fehler und Dry-Runs erhalten es; just clean räumt separat auf. Globale Cargo-/Rustup-/Docker-Caches und Anwendungsdaten bleiben erhalten. Der nächste lokale Build erzeugt seine Ausgaben neu; notwendige kompakte Nachweise vorher dokumentieren. Direkte git push-Aufrufe und IDE-Pushes lösen die Bereinigung nicht aus; Git hat keinen lokalen Post-Push-Hook.

Coverage und Browserwerkzeuge lassen scripts/prepare-build.sh das eigene target/ zuerst durch einen echten, gelockten Cargo-Check der bereits vorhandenen kleinen Dependency initialisieren: Bei einem zuvor durch andere Tools angelegten Verzeichnis kehrt Cargo 1.99 vor der Marker-Erzeugung zurück. Erst danach entstehen die Tool-Unterverzeichnisse. Cargo selbst erzeugt den Cache-Marker; ein schon vorhandenes target/ wird nur mit regulärem, gültigem Marker akzeptiert. Unmarkierte Altverzeichnisse und Symlinks benötigen eine gezielte manuelle Migrationsprüfung und bleiben unverändert; weder Marker-Kopien noch automatische Reparaturen legitimieren ihre Löschung. Explizite lokale Cargo-Ausgabepfade erhalten externe Buildverzeichnisse. Nach erfolgreichem just push entfernt echtes Cargo das gesamte lokale target/; fehlgeschlagene Pushes und Dry-Runs erhalten es.

Workspace-Nachweis vom 04.10.2026: vollständiger just gate Exit0; 23 Nodefälle einschließlich 18 echter Initialisierungs-/Push-/Coverage-/Browser-Fixtures und deren Fehlerpfade, Common-AllFeatures60/60 sowie UI15/15 und sämtliche weiteren Feature-/HTTP-/Browserprüfungen grün. Der gezielte Fixturelauf ist auch unter der echten äußeren Coverage-Umgebung 18/18; diese Umgebung wird für isolierte Fixtures entfernt und innerhalb ihrer eigenen Coverageprüfung frisch eingerichtet. Stable-Coverage: 1.699/1.878 Lines=90,47% und 2.504/2.764 Regions=90,59%; Branch-/Doctestcoverage nicht gemessen. Globale/externe Ausgabepfade und unmarkierte Altverzeichnisse bleiben erhalten.