use std::io::Write;
use std::process::Stdio;
fn main() {
let should_build = std::env::var_os("CARGO_FEATURE_BUILD").is_some();
let only_check = std::env::var_os("CARGO_FEATURE_ONLY_CHECK").is_some();
if !(should_build || only_check) {
return;
}
let wasms_path = format!("{}/{}/", env!("CARGO_MANIFEST_DIR"), "wasm_workspace");
println!("cargo:rerun-if-changed=Cargo.toml");
println!("cargo:rerun-if-changed=../../../Cargo.lock");
for dir in parse_cargo_toml_local_dependency_paths() {
for item in walkdir::WalkDir::new(dir)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
println!("cargo:rerun-if-changed={}", item.path().display());
}
}
for item in walkdir::WalkDir::new(wasms_path.clone())
.into_iter()
.filter_entry(|e| {
e.file_name()
.to_str()
.map(|e| e != "target")
.unwrap_or(false)
})
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
println!("cargo:rerun-if-changed={}", item.path().display());
}
let wasm_out = std::env::var_os("HC_TEST_WASM_DIR");
let cargo_command = std::env::var_os("CARGO");
let cargo_command = cargo_command.as_deref().unwrap_or_else(|| "cargo".as_ref());
build_test_wasms(&wasm_out, cargo_command, should_build, false, &wasms_path);
build_test_wasms(&wasm_out, cargo_command, should_build, true, &wasms_path);
}
fn build_test_wasms(
wasm_out: &Option<std::ffi::OsString>,
cargo_command: &std::ffi::OsStr,
should_build: bool,
build_integrity_zomes: bool,
wasms_path: &str,
) {
let mut cmd = std::process::Command::new(cargo_command);
cmd.env_remove("RUSTFLAGS");
cmd.env_remove("CARGO_BUILD_RUSTFLAGS");
cmd.env_remove("CARGO_ENCODED_RUSTFLAGS");
if should_build {
cmd.stdout(Stdio::piped());
cmd.stderr(Stdio::piped());
cmd.env("RUSTFLAGS", "-C opt-level=z");
cmd.arg("build")
.arg("--manifest-path")
.arg("wasm_workspace/Cargo.toml")
.arg("--release")
.arg("--workspace")
.arg("--target")
.arg("wasm32-unknown-unknown");
} else {
cmd.arg("check")
.arg("--manifest-path")
.arg("wasm_workspace/Cargo.toml");
}
if build_integrity_zomes {
cmd.arg("--examples");
cmd.arg("--no-default-features");
cmd.arg("--features");
cmd.arg("integrity");
}
match wasm_out {
Some(wasm_out) => {
cmd.env("CARGO_TARGET_DIR", wasm_out);
}
None => {
cmd.env("CARGO_TARGET_DIR", format!("{}/target", wasms_path));
}
}
let output = cmd.output().unwrap();
if !output.status.success() {
std::io::stderr().write_all(&output.stderr).ok();
assert!(output.status.success());
}
}
fn parse_cargo_toml_local_dependency_paths() -> Vec<String> {
let cargo_toml: toml::Value = std::fs::read_to_string("Cargo.toml")
.unwrap()
.parse()
.unwrap();
let mut table = toml_table(cargo_toml);
let deps: Vec<_> = match (
table.remove("dependencies"),
table.remove("dev-dependencies"),
) {
(Some(deps), Some(dev_deps)) => toml_table(deps)
.values()
.chain(toml_table(dev_deps).values())
.cloned()
.collect(),
(Some(deps), None) => toml_table(deps).values().cloned().collect(),
(None, Some(dev_deps)) => toml_table(dev_deps).values().cloned().collect(),
(None, None) => Vec::new(),
};
deps.into_iter()
.filter_map(|v| {
if let toml::Value::Table(mut table) = v {
table.remove("path").map(toml_string)
} else {
None
}
})
.collect()
}
fn toml_string(value: toml::Value) -> String {
if let toml::Value::String(string) = value {
string
} else {
panic!("Expected TOML string, got: {:?}", value)
}
}
fn toml_table(value: toml::Value) -> toml::value::Table {
if let toml::Value::Table(table) = value {
table
} else {
panic!("Expected TOML table, got: {:?}", value)
}
}