use std::collections::HashMap;
use std::process::{Command, Output};
use std::sync::{LazyLock, Mutex};
const LLVM_RELEASES: std::ops::RangeInclusive<u32> = 16..=22;
pub(crate) fn required_tool(name: &str) -> String {
static RESOLVED: LazyLock<Mutex<HashMap<String, String>>> =
LazyLock::new(|| Mutex::new(HashMap::new()));
if let Some(found) = RESOLVED.lock().unwrap().get(name) {
return found.clone();
}
let candidates = std::iter::once(name.to_owned()).chain(
LLVM_RELEASES
.rev()
.map(|release| format!("{name}-{release}")),
);
let mut attempted = Vec::new();
for candidate in candidates {
if Command::new(&candidate).arg("--version").output().is_ok() {
RESOLVED
.lock()
.unwrap()
.insert(name.to_owned(), candidate.clone());
return candidate;
}
attempted.push(candidate);
}
panic!(
"required test tool is unavailable: {}",
attempted.join(", ")
)
}
pub(crate) fn run(command: &mut Command) -> Output {
let output = command.output().unwrap();
assert!(
output.status.success(),
"command failed:\nstdout: {}\nstderr: {}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
output
}