1#![forbid(unsafe_code)]
2
3use std::env;
4use std::path::PathBuf;
5
6pub fn resolve(binary: &str) -> Option<PathBuf> {
7 if let Some(override_bin) = override_binary(binary)
8 && override_bin.exists()
9 {
10 return Some(override_bin);
11 }
12 if let Some(path_bin) = resolve_from_path(binary) {
13 return Some(path_bin);
14 }
15 if let Some(current_exe) = std::env::current_exe().ok()
16 && let Some(exe_dir) = current_exe.parent()
17 {
18 let local_bin = exe_dir.join(binary);
19 if local_bin.exists() {
20 return Some(local_bin);
21 }
22 }
23 None
24}
25
26fn override_binary(binary: &str) -> Option<PathBuf> {
27 let keys: &[&str] = match binary {
28 "greentic-flow" => &["GREENTIC_FLOW_BIN", "GREENTIC_FLOW_DEV_BIN"],
29 "greentic-component" => &["GREENTIC_COMPONENT_BIN", "GREENTIC_COMPONENT_DEV_BIN"],
30 _ => return None,
31 };
32 keys.iter()
33 .find_map(|key| env::var_os(key).map(PathBuf::from))
34}
35
36fn resolve_from_path(binary: &str) -> Option<PathBuf> {
37 let path_var = env::var_os("PATH")?;
38 for dir in env::split_paths(&path_var) {
39 let candidate = dir.join(binary);
40 if candidate.exists() {
41 return Some(candidate);
42 }
43 }
44 None
45}