use anyhow::{ensure, Result};
use std::{env, path::PathBuf, process::Command};
use crate::builder_error::BuilderError;
pub struct CargoCommand {
path: String,
manifest_path: PathBuf,
args: Vec<&'static str>,
profile: String,
rustc_flags: Vec<&'static str>,
target_dir: PathBuf,
}
impl CargoCommand {
pub fn new() -> Self {
CargoCommand {
path: "rustup".to_string(),
manifest_path: "Cargo.toml".into(),
args: vec![
"run",
"nightly",
"cargo",
"rustc",
"--target=wasm32-unknown-unknown",
],
profile: "dev".to_string(),
rustc_flags: vec!["-C", "link-arg=--import-memory", "-C", "linker-plugin-lto"],
target_dir: "target".into(),
}
}
pub fn set_manifest_path(&mut self, path: PathBuf) {
self.manifest_path = path;
}
pub fn set_target_dir(&mut self, path: PathBuf) {
self.target_dir = path;
}
pub fn set_profile(&mut self, profile: String) {
self.profile = profile;
}
pub fn run(&self) -> Result<()> {
let mut cargo = Command::new(&self.path);
cargo
.args(&self.args)
.arg("--color=always")
.arg(format!("--manifest-path={}", self.manifest_path.display()))
.arg("--profile")
.arg(&self.profile)
.arg("--")
.args(&self.rustc_flags)
.env("CARGO_TARGET_DIR", &self.target_dir)
.env(self.skip_build_env(), "");
self.remove_cargo_encoded_rustflags(&mut cargo);
let status = cargo.status()?;
ensure!(
status.success(),
BuilderError::CargoRunFailed(status.to_string())
);
Ok(())
}
pub fn skip_build_env(&self) -> String {
format!(
"SKIP_{}_WASM_BUILD",
env::var("CARGO_PKG_NAME")
.expect("Package name is set")
.to_uppercase()
.replace('-', "_"),
)
}
fn remove_cargo_encoded_rustflags(&self, command: &mut Command) {
command.env_remove("CARGO_ENCODED_RUSTFLAGS");
command.env_remove("RUSTFLAGS");
}
}