greentic_dev/
passthrough.rs1use anyhow::{Context, Result, anyhow, bail};
2use std::env;
3use std::ffi::OsString;
4use std::path::{Path, PathBuf};
5use std::process::{Command, ExitStatus, Stdio};
6
7pub fn resolve_binary(name: &str) -> Result<PathBuf> {
9 let env_key = format!("GREENTIC_DEV_BIN_{}", name.replace('-', "_").to_uppercase());
10 if let Ok(path) = env::var(&env_key) {
11 let pb = PathBuf::from(path);
12 if pb.exists() {
13 return Ok(pb);
14 }
15 bail!("{env_key} points to non-existent binary: {}", pb.display());
16 }
17
18 if let Ok(path) = which::which(name) {
19 return Ok(path);
20 }
21
22 if let Ok(cwd) = env::current_dir() {
24 for dir in ["target/debug", "target/release"] {
25 let candidate = cwd.join(dir).join(name);
26 if candidate.exists() {
27 return Ok(candidate);
28 }
29 }
30 }
31
32 which::which(name).with_context(|| {
33 format!("failed to find `{name}` in PATH; set {env_key} or install {name}")
34 })
35}
36
37pub fn run_passthrough(bin: &Path, args: &[OsString], verbose: bool) -> Result<ExitStatus> {
38 if verbose {
39 eprintln!("greentic-dev passthrough -> {} {:?}", bin.display(), args);
40 let _ = Command::new(bin)
41 .arg("--version")
42 .stdout(Stdio::inherit())
43 .stderr(Stdio::inherit())
44 .status();
45 }
46
47 Command::new(bin)
48 .args(args)
49 .stdin(Stdio::inherit())
50 .stdout(Stdio::inherit())
51 .stderr(Stdio::inherit())
52 .status()
53 .map_err(|e| anyhow!("failed to execute {}: {e}", bin.display()))
54}