From 4d8e27cd5021e8e62a69076027f3dccc8e7fae0a Mon Sep 17 00:00:00 2001 From: Danny Date: Thu, 19 Mar 2026 16:40:52 +0100 Subject: [PATCH] Fix OVMF 4m variant detection and Gentoo dep atom parsing 1. host.ovmf: Arch edk2-ovmf 202508+ uses OVMF_CODE.4m.fd (4MB variant) instead of OVMF_CODE.fd. Added .4m.fd paths to the search list and updated the find fallback to match OVMF_CODE*.fd glob. 2. test_parse_dep_atoms: The single-regex approach with lazy quantifiers failed on atoms like "sys-libs/zlib" at end-of-string. Rewrote parse_dep_atoms to split on whitespace first, strip [:slot] and [USE] suffixes, then match category/name with a simple anchored regex. This is more robust and easier to reason about. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/dpack/src/converter/gentoo.rs | 61 +++++++++++++++++++++++-------- tests/proxmox/run-in-vm.sh | 7 +++- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/dpack/src/converter/gentoo.rs b/src/dpack/src/converter/gentoo.rs index ec560c8..ca92e0e 100644 --- a/src/dpack/src/converter/gentoo.rs +++ b/src/dpack/src/converter/gentoo.rs @@ -321,27 +321,56 @@ fn parse_use_flags(iuse: &str) -> HashMap { /// Strips category prefixes and version constraints for dpack format. fn parse_dep_atoms(deps: &str, warnings: &mut ConversionWarnings) -> Vec { let mut result = Vec::new(); + // Regex to extract category/name from a single Gentoo atom token + // Strips: leading operator (>=, <=, ~, =), trailing version (-1.2.3), + // slot (:0=), and USE flags ([foo,bar]) let atom_re = Regex::new( - r"(?:>=|<=|~|=)?([a-zA-Z0-9_-]+/[a-zA-Z0-9_.+-]+?)(?:-\d[^\s\[\]:]*)?(?:\[.*?\])?(?::[\w/=*]*)?(?:\s|$)" + r"^(?:>=|<=|~|=)?([a-zA-Z0-9_-]+/[a-zA-Z0-9_+-]+[a-zA-Z])" ).unwrap(); - for caps in atom_re.captures_iter(deps) { - if let Some(m) = caps.get(1) { - let full_atom = m.as_str(); - // Strip category prefix (e.g., "dev-libs/" -> "") - let pkg_name = full_atom - .rsplit('/') - .next() - .unwrap_or(full_atom) - .to_string(); + // Process each whitespace-separated token, skipping non-atoms + for token in deps.split_whitespace() { + let clean = token.trim(); - // Skip virtual packages and test-only deps - if full_atom.starts_with("virtual/") { - continue; - } + // Skip conditional operators and parens + if clean.is_empty() + || clean.ends_with('?') + || clean == "(" + || clean == ")" + || clean == "||" + || clean == "^^" + { + continue; + } - if !result.contains(&pkg_name) { - result.push(pkg_name); + // Strip trailing [:slot] and [USE] before regex matching + let without_use = if let Some(bracket_pos) = clean.find('[') { + &clean[..bracket_pos] + } else { + clean + }; + let without_slot = if let Some(colon_pos) = without_use.find(':') { + &without_use[..colon_pos] + } else { + without_use + }; + + if let Some(caps) = atom_re.captures(without_slot) { + if let Some(m) = caps.get(1) { + let full_atom = m.as_str(); + let pkg_name = full_atom + .rsplit('/') + .next() + .unwrap_or(full_atom) + .to_string(); + + if full_atom.starts_with("virtual/") { + continue; + } + + if !result.contains(&pkg_name) { + result.push(pkg_name); + } } } } diff --git a/tests/proxmox/run-in-vm.sh b/tests/proxmox/run-in-vm.sh index ac94084..b50afe5 100755 --- a/tests/proxmox/run-in-vm.sh +++ b/tests/proxmox/run-in-vm.sh @@ -133,11 +133,14 @@ else record "host.nested_virt" "skip" "No VMX/SVM — QEMU boot tests will be slower" fi -# Check OVMF — Arch uses split CODE/VARS files, others use a single OVMF.fd +# Check OVMF — search all known paths including 4m variant (newer Arch) OVMF="" for p in \ + /usr/share/edk2/x64/OVMF_CODE.4m.fd \ /usr/share/edk2/x64/OVMF_CODE.fd \ + /usr/share/edk2-ovmf/x64/OVMF_CODE.4m.fd \ /usr/share/edk2-ovmf/x64/OVMF_CODE.fd \ + /usr/share/OVMF/OVMF_CODE.4m.fd \ /usr/share/OVMF/OVMF_CODE.fd \ /usr/share/edk2/x64/OVMF.fd \ /usr/share/edk2-ovmf/x64/OVMF.fd \ @@ -148,7 +151,7 @@ for p in \ done # Last resort: find it if [ -z "$OVMF" ]; then - OVMF=$(find /usr/share -name "OVMF_CODE.fd" -o -name "OVMF.fd" 2>/dev/null | head -1) + OVMF=$(find /usr/share -name "OVMF_CODE*.fd" -o -name "OVMF.fd" 2>/dev/null | head -1) fi [ -n "$OVMF" ] && record "host.ovmf" "pass" "$OVMF" || record "host.ovmf" "fail" "Not found — install edk2-ovmf"