beet_cli/commands/
cargo_cmd.rs1use anyhow::Result;
2use clap::Parser;
3use std::path::PathBuf;
4use std::process::Command;
5
6#[derive(Debug, Clone, Parser)]
8#[command(name = "cargo-cmd")]
9pub struct CargoCmd {
10 #[arg(long, default_value = "build")]
12 pub cargo_cmd: String,
13 #[arg(long)]
14 pub message_format: Option<String>,
15 #[arg(short = 'v', long, action = clap::ArgAction::Count)]
17 pub verbose: u8,
18 #[arg(short, long)]
20 pub quiet: bool,
21 #[arg(long)]
23 pub color: Option<String>,
24 pub config: Option<String>,
26 #[arg(short = 'Z', long)]
28 pub z: Option<String>,
29 #[arg(short = 'p', long = "package")]
31 pub package: Option<String>,
32 #[arg(long)]
34 pub bin: Option<String>,
35 #[arg(long)]
37 pub example: Option<String>,
38 #[arg(short = 'F', long = "features")]
40 pub features: Option<String>,
41 #[arg(long)]
43 pub all_features: bool,
44 #[arg(long)]
46 pub no_default_features: bool,
47 #[arg(short = 'j', long)]
49 pub jobs: Option<String>,
50 #[arg(long)]
52 pub keep_going: bool,
53 #[arg(long)]
55 pub release: bool,
56 #[arg(long)]
58 pub profile: Option<String>,
59 #[arg(long)]
61 pub target: Option<String>,
62 #[arg(long)]
64 pub target_dir: Option<String>,
65 #[arg(long)]
67 pub unit_graph: bool,
68 #[arg(long)]
70 pub timings: Option<String>,
71 #[arg(long)]
73 pub manifest_path: Option<String>,
74 #[arg(long)]
76 pub lockfile_path: Option<String>,
77 #[arg(long)]
79 pub ignore_rust_version: bool,
80 #[arg(long)]
82 pub locked: bool,
83 #[arg(long)]
85 pub offline: bool,
86 #[arg(long)]
88 pub frozen: bool,
89 #[arg(trailing_var_arg = true)]
91 pub args: Vec<String>,
92}
93
94impl Default for CargoCmd {
95 fn default() -> Self { Self::parse_from(&[""]) }
96}
97
98impl CargoCmd {
99 pub fn exe_path(&self) -> PathBuf {
102 let target_dir = std::env::var("CARGO_TARGET_DIR")
103 .unwrap_or_else(|_| "target".to_string());
104 let mut path = PathBuf::from(target_dir);
105
106 if let Some(target) = &self.target {
107 path.push(target);
108 }
109
110 if self.release {
111 path.push("release");
112 } else {
113 path.push("debug");
114 }
115
116 if let Some(example) = &self.example {
117 path.push("examples");
118 path.push(example);
119 } else if let Some(pkg) = &self.package {
121 path.push(pkg);
122 }
123 if let Some(bin) = &self.bin {
124 path.push(bin);
125 }
126
127 if let Some("wasm32-unknown-unknown") = self.target.as_deref() {
128 path.set_extension("wasm");
129 }
130
131 path
132 }
133
134 pub fn spawn(&self) -> Result<()> {
135 let CargoCmd {
136 cargo_cmd,
137 args,
138 message_format,
139 verbose,
140 quiet,
141 color,
142 config,
143 z,
144 package,
145 bin,
146 example,
147 features,
148 all_features,
149 no_default_features,
150 jobs,
151 keep_going,
152 release,
153 profile,
154 target,
155 target_dir,
156 unit_graph,
157 timings,
158 manifest_path,
159 lockfile_path,
160 ignore_rust_version,
161 locked,
162 offline,
163 frozen,
164 } = self;
165 let mut cmd = Command::new("cargo");
166 cmd.arg(cargo_cmd);
167
168
169 if let Some(format) = message_format {
170 cmd.arg("--message-format").arg(format);
171 }
172
173 for _ in 0..*verbose {
174 cmd.arg("-v");
175 }
176
177 if *quiet {
178 cmd.arg("--quiet");
179 }
180
181 if let Some(c) = color {
182 cmd.arg("--color").arg(c);
183 }
184
185 if let Some(cfg) = config {
186 cmd.arg("--config").arg(cfg);
187 }
188
189 if let Some(z_flag) = z {
190 cmd.arg("-Z").arg(z_flag);
191 }
192
193 if let Some(pkg) = package {
194 cmd.arg("--package").arg(pkg);
195 }
196
197 if let Some(b) = bin {
198 cmd.arg("--bin").arg(b);
199 }
200
201 if let Some(ex) = example {
202 cmd.arg("--example").arg(ex);
203 }
204
205 if let Some(feat) = features {
206 cmd.arg("--features").arg(feat);
207 }
208
209 if *all_features {
210 cmd.arg("--all-features");
211 }
212
213 if *no_default_features {
214 cmd.arg("--no-default-features");
215 }
216
217 if let Some(j) = jobs {
218 cmd.arg("-j").arg(j);
219 }
220
221 if *keep_going {
222 cmd.arg("--keep-going");
223 }
224
225 if *release {
226 cmd.arg("--release");
227 }
228
229 if let Some(prof) = profile {
230 cmd.arg("--profile").arg(prof);
231 }
232
233 if let Some(tgt) = target {
234 cmd.arg("--target").arg(tgt);
235 }
236
237 if let Some(dir) = target_dir {
238 cmd.arg("--target-dir").arg(dir);
239 }
240
241 if *unit_graph {
242 cmd.arg("--unit-graph");
243 }
244
245 if let Some(tim) = timings {
246 cmd.arg("--timings").arg(tim);
247 }
248
249 if let Some(path) = manifest_path {
250 cmd.arg("--manifest-path").arg(path);
251 }
252
253 if let Some(lock) = lockfile_path {
254 cmd.arg("--lockfile-path").arg(lock);
255 }
256
257 if *ignore_rust_version {
258 cmd.arg("--ignore-rust-version");
259 }
260
261 if *locked {
262 cmd.arg("--locked");
263 }
264
265 if *offline {
266 cmd.arg("--offline");
267 }
268
269 if *frozen {
270 cmd.arg("--frozen");
271 }
272
273 cmd.args(args);
274
275 cmd.status()?.exit_ok()?;
276 Ok(())
277 }
278}
279
280