use std::path::PathBuf;
use std::process::Command;
use crate::kernel::{
encode_kernel_list, path_kernel_label, resolve_kernel_image, resolve_kernel_set,
};
pub(crate) fn run_verifier(kernel: Vec<String>, raw: bool) -> Result<(), String> {
let mut cmd = Command::new("cargo");
cmd.args(["nextest", "run", "-E", "test(/^verifier/)"]);
if raw {
cmd.env(ktstr::KTSTR_VERIFIER_RAW_ENV, "1");
}
let resolved: Vec<(String, PathBuf)> = if !kernel.is_empty() {
let r = resolve_kernel_set(&kernel)?;
if r.is_empty() {
return Err(
"--kernel: every supplied value parsed to empty / whitespace; \
omit the flag for auto-discovery, or supply a kernel \
identifier"
.to_string(),
);
}
r
} else {
let path = resolve_kernel_image(None)?;
let label = path_kernel_label(&path);
vec![(label, path)]
};
cmd.env(ktstr::KTSTR_KERNEL_ENV, &resolved[0].1);
let encoded = encode_kernel_list(&resolved)?;
cmd.env(ktstr::KTSTR_KERNEL_LIST_ENV, encoded);
let kernel_count = resolved.len();
eprintln!(
"cargo ktstr verifier: dispatching to nextest with filter test(/^verifier/) \
on {kernel_count} resolved kernel(s){raw}",
raw = if raw { " (raw output)" } else { "" },
);
let status = cmd
.status()
.map_err(|e| format!("spawn cargo nextest run: {e}"))?;
if status.success() {
Ok(())
} else {
Err(format!(
"cargo nextest run exited with {}",
status
.code()
.map_or("signal".to_string(), |c| c.to_string()),
))
}
}