diff --git a/Cargo.lock b/Cargo.lock index 1f51225..67e9ca9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1364,6 +1364,7 @@ dependencies = [ "regex", "reqwest", "scraper", + "semver", "serde", "serde_json", "spinners", @@ -1934,6 +1935,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" diff --git a/Cargo.toml b/Cargo.toml index 1843a27..0dd6af4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ md5 = "0.8.0" # HTTP reqwest = { version = "0.12.23", features = ["blocking", "json"] } +semver = "1.0.27" [features] # TUI feature flag diff --git a/src/main.rs b/src/main.rs index debfdb4..33eb9f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,16 +19,23 @@ fn main() -> Result<(), Box> { { // TUI-Modus tui::tui_menu()?; - Ok(()) + return Ok(()); } #[cfg(not(feature = "tui"))] { - // --- Dynamische Version-Prüfung aus HTML --- - let json = html::fetch_and_parse_html_to_json( + // --- Dynamische Version-Prüfung direkt aus HTML --- + let ok = version_check::run_version_checks_from_html( "https://www.linuxfromscratch.org/~thomas/multilib-m32/chapter02/hostreqs.html", )?; - version_check::run_version_checks_from_json(&json); + + if !ok { + eprintln!( + "{} Some version checks failed. Exiting.", + style("❌").red().bold() + ); + std::process::exit(1); + } println!( "{} All version checks passed. Starting downloader...", diff --git a/src/version_check.rs b/src/version_check.rs index b950c7e..f14106b 100644 --- a/src/version_check.rs +++ b/src/version_check.rs @@ -1,5 +1,6 @@ use reqwest; use scraper::{Html, Selector}; +use semver::Version; use std::process::Command; /// Führt ein Kommando aus und gibt die erste Zeile der Version zurück @@ -12,8 +13,18 @@ fn run_command(cmd: &str, args: &[&str]) -> Option { } } -/// Vergleicht zwei Versionen +/// Vergleicht zwei Versionen mit semver (für Programme) fn check_version(installed: &str, required: &str) -> bool { + let i = Version::parse(installed).ok(); + let r = Version::parse(required).ok(); + match (i, r) { + (Some(i), Some(r)) => i >= r, + _ => false, + } +} + +/// Vergleicht Kernel-Versionen (numerisch) +fn check_kernel_version(installed: &str, required: &str) -> bool { let parse_ver = |v: &str| { v.split(['.', '-']) .filter_map(|s| s.parse::().ok()) @@ -48,7 +59,7 @@ fn ver_check(program: &str, cmd: &str, min_version: &str) -> bool { println!("OK: {:<12} {:<8} >= {}", program, ver, min_version); true } else { - println!( + eprintln!( "ERROR: {:<12} version {} is too old ({} required)", program, ver, min_version ); @@ -56,7 +67,7 @@ fn ver_check(program: &str, cmd: &str, min_version: &str) -> bool { } } None => { - println!("ERROR: Cannot find {}", program); + eprintln!("ERROR: Cannot find {}", program); false } } @@ -65,11 +76,11 @@ fn ver_check(program: &str, cmd: &str, min_version: &str) -> bool { /// Führt die Kernel-Prüfung durch fn ver_kernel(min_version: &str) -> bool { let kernel = run_command("uname", &["-r"]).unwrap_or_default(); - if check_version(&kernel, min_version) { + if check_kernel_version(&kernel, min_version) { println!("OK: Linux Kernel {} >= {}", kernel, min_version); true } else { - println!( + eprintln!( "ERROR: Linux Kernel {} is too old ({} required)", kernel, min_version ); @@ -78,7 +89,7 @@ fn ver_kernel(min_version: &str) -> bool { } /// Lädt die LFS-Seite und führt alle Versionsprüfungen aus -pub fn run_version_checks_from_html(url: &str) -> Result<(), Box> { +pub fn run_version_checks_from_html(url: &str) -> Result> { let html_text = reqwest::blocking::get(url)?.text()?; let document = Html::parse_document(&html_text); let selector = Selector::parse("pre").unwrap(); @@ -112,7 +123,7 @@ pub fn run_version_checks_from_html(url: &str) -> Result<(), Box Result<(), Box