feat: recipe durability guard — prevents build system from deleting local recipes

Add guard-recipes.sh with four modes:
- --verify: check all local/recipes have correct symlinks into recipes/
- --fix: repair broken symlinks (run before builds)
- --save-all: snapshot all recipe.toml into local/recipes/
- --restore: recreate all symlinks from local/recipes/ (run after sync-upstream)

Wired into apply-patches.sh (post-patch) and sync-upstream.sh (post-sync).
This prevents the build system from deleting recipe files during
cargo cook, make distclean, or upstream source refresh.
This commit is contained in:
2026-04-30 18:47:03 +01:00
parent 34360e1e4f
commit 7c7399e0a6
126 changed files with 13145 additions and 178 deletions
@@ -29,3 +29,4 @@ template = "cargo"
"/usr/bin/redbear-boot-check" = "redbear-boot-check"
"/usr/bin/redbear-phase6-kde-check" = "redbear-phase6-kde-check"
"/usr/bin/redbear-phase5-cs-check" = "redbear-phase5-cs-check"
"/usr/bin/cmdline" = "cmdline"
@@ -75,6 +75,10 @@ path = "src/bin/redbear-phase-iommu-check.rs"
name = "redbear-phase-ps2-check"
path = "src/bin/redbear-phase-ps2-check.rs"
[[bin]]
name = "cmdline"
path = "src/bin/cmdline.rs"
[[bin]]
name = "redbear-phase-timer-check"
path = "src/bin/redbear-phase-timer-check.rs"
@@ -0,0 +1,39 @@
use std::env;
use std::fs;
fn main() {
let args: Vec<String> = env::args().collect();
// Read /scheme/sys/env for cmdline parameters
let env_data = match fs::read_to_string("/scheme/sys/env") {
Ok(d) => d,
Err(_) => {
// Fallback: read process environment
let vars: Vec<String> = env::vars()
.filter(|(k, _)| k.starts_with("CMDLINE_"))
.map(|(k, v)| format!("{}={}", k.trim_start_matches("CMDLINE_"), v))
.collect();
if vars.is_empty() {
eprintln!("cmdline: no parameters found");
return;
}
vars.join("\n")
}
};
if args.len() >= 3 && args[1] == "--get" {
let key = &args[2];
for line in env_data.lines() {
if let Some((k, v)) = line.split_once('=') {
if k == key {
println!("{}", v);
return;
}
}
}
eprintln!("cmdline: {} not found", key);
std::process::exit(1);
}
println!("{}", env_data);
}
@@ -104,6 +104,28 @@ fn lookup_quirks(
lookup_pci_quirks(&info)
}
fn resolve_driver_params(loc: &str) -> Option<HashMap<String, String>> {
let base = format!("/tmp/redbear-driver-params/{}", loc);
let dir = std::fs::read_dir(&base).ok()?;
let mut params = HashMap::new();
for entry in dir.flatten() {
let name = match entry.file_name().into_string() {
Ok(n) => n,
Err(_) => continue,
};
let value = match std::fs::read_to_string(entry.path()) {
Ok(v) => v,
Err(_) => continue,
};
params.insert(name, value.trim().to_string());
}
if params.is_empty() {
None
} else {
Some(params)
}
}
fn collect_runtime_irq_modes() -> HashMap<String, String> {
let mut modes = HashMap::new();
for dir in [
@@ -188,6 +210,13 @@ fn run() -> Result<(), String> {
if let Some(mode) = runtime_modes.get(&loc_key) {
print!(" runtime-mode: {mode}");
}
if let Some(params) = resolve_driver_params(&loc_key) {
let param_str: Vec<String> = params
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect();
print!(" driver-params: {}", param_str.join(" "));
}
println!();
}