use std::path::PathBuf;
use contract_build::{
CrateMetadata,
Features,
ManifestPath,
VerbosityFlags,
util,
};
#[derive(Debug, clap::Args)]
#[clap(name = "test")]
pub struct TestCommand {
#[clap(long, value_parser)]
manifest_path: Option<PathBuf>,
#[clap(flatten)]
features: Features,
#[clap(long)]
all_features: bool,
#[clap(flatten)]
verbosity: VerbosityFlags,
#[clap(long)]
nocapture: bool,
#[arg(last = true)]
args: Vec<String>,
}
impl TestCommand {
pub fn run(&self) -> anyhow::Result<()> {
let manifest_path = ManifestPath::try_from(self.manifest_path.as_ref())?;
let mut args = vec![manifest_path.cargo_arg()?];
self.features.append_to_args(&mut args);
if self.all_features {
args.push("--all-features".to_string());
}
if !self.args.is_empty() {
args.extend(self.args.clone());
}
if self.nocapture {
if !self.args.iter().any(|arg| arg == "--") {
args.push("--".to_string());
}
args.push("--nocapture".to_string());
}
let mut env = Vec::new();
let crate_metadata = CrateMetadata::collect(&manifest_path)?;
if let Some(abi) = crate_metadata.abi {
env.push((
"CARGO_ENCODED_RUSTFLAGS",
Some(abi.cargo_encoded_rustflag()),
));
}
let verbosity = TryFrom::<&VerbosityFlags>::try_from(&self.verbosity)?;
let cmd = util::cargo_cmd(
"test",
args,
crate_metadata.manifest_path.directory(),
verbosity,
env,
);
let output = cmd.run()?;
if !output.status.success() {
anyhow::bail!(
"Failed to run `cargo test`{}",
if output.stderr.is_empty() {
String::new()
} else {
format!(": {}", String::from_utf8_lossy(&output.stderr))
}
)
}
Ok(())
}
}