1use std::ops::{Deref, DerefMut};
2use std::path::PathBuf;
3use std::process::{self, Command};
4
5use anyhow::{Context, Result};
6use clap::Parser;
7
8use crate::Zig;
9
10#[derive(Clone, Debug, Default, Parser)]
12#[command(
13 display_order = 1,
14 after_help = "Run `cargo help test` for more detailed information.\nRun `cargo test -- --help` for test binary options."
15)]
16pub struct Test {
17 #[arg(skip)]
19 pub disable_zig_linker: bool,
20
21 #[arg(skip)]
23 pub enable_zig_ar: bool,
24
25 #[arg(skip)]
27 pub macosx_deployment_target: Option<String>,
28
29 #[command(flatten)]
30 pub cargo: cargo_options::Test,
31}
32
33impl Test {
34 #[allow(clippy::field_reassign_with_default)]
36 pub fn new(manifest_path: Option<PathBuf>) -> Self {
37 let mut build = Self::default();
38 build.manifest_path = manifest_path;
39 build
40 }
41
42 pub fn execute(&self) -> Result<()> {
44 let mut test = self.build_command()?;
45
46 let mut child = test.spawn().context("Failed to run cargo test")?;
47 let status = child.wait().expect("Failed to wait on cargo test process");
48 if !status.success() {
49 process::exit(status.code().unwrap_or(1));
50 }
51 Ok(())
52 }
53
54 pub fn build_command(&self) -> Result<Command> {
56 let mut build = self.cargo.command();
57 if !self.disable_zig_linker {
58 Zig::apply_command_env(
59 self.manifest_path.as_deref(),
60 self.release,
61 &self.cargo.common,
62 &mut build,
63 self.enable_zig_ar,
64 self.macosx_deployment_target.as_deref(),
65 )?;
66 }
67
68 Ok(build)
69 }
70}
71
72impl Deref for Test {
73 type Target = cargo_options::Test;
74
75 fn deref(&self) -> &Self::Target {
76 &self.cargo
77 }
78}
79
80impl DerefMut for Test {
81 fn deref_mut(&mut self) -> &mut Self::Target {
82 &mut self.cargo
83 }
84}
85
86impl From<cargo_options::Test> for Test {
87 fn from(cargo: cargo_options::Test) -> Self {
88 Self {
89 cargo,
90 ..Default::default()
91 }
92 }
93}