use std::process::Command;
type TestResult = Result<(), Box<dyn std::error::Error>>;
#[test]
fn published_crate_includes_ops_console_bundle() -> TestResult {
let cargo = env!("CARGO");
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let output = Command::new(cargo)
.args([
"package",
"--list",
"--offline",
"--allow-dirty",
"--manifest-path",
])
.arg(format!("{manifest_dir}/Cargo.toml"))
.output()?;
if !output.status.success() {
return Err(format!(
"`cargo package --list` failed:\nstdout:\n{}\nstderr:\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr),
)
.into());
}
let listing = String::from_utf8(output.stdout)?;
let packaged: Vec<&str> = listing.lines().map(str::trim).collect();
if !packaged.contains(&"ops-console-embed/index.html") {
return Err(format!(
"published aion-server crate is MISSING `ops-console-embed/index.html`: a \
`cargo install` would ship an API-only binary with no ops console. \
Packaged files:\n{listing}"
)
.into());
}
let has_hashed_asset = packaged.iter().any(|path| {
path.starts_with("ops-console-embed/assets/")
&& std::path::Path::new(path)
.extension()
.and_then(std::ffi::OsStr::to_str)
.is_some_and(|ext| {
ext.eq_ignore_ascii_case("js") || ext.eq_ignore_ascii_case("css")
})
});
if !has_hashed_asset {
return Err(format!(
"published aion-server crate ships no `ops-console-embed/assets/*.{{js,css}}` \
bundle: the embedded ops console would be non-functional after `cargo \
install`. Packaged files:\n{listing}"
)
.into());
}
Ok(())
}