pub(crate) fn bin_dir(bin: &str) -> Option<String> {
let path = std::env::var("PATH").ok()?;
bin_dir_in(&path, bin)
}
pub(crate) fn bin_dir_in(path: &str, bin: &str) -> Option<String> {
path.split(':')
.filter(|dir| !dir.is_empty())
.find(|dir| std::path::Path::new(dir).join(bin).is_file())
.map(str::to_string)
}
pub(crate) fn tmux_available_in(path: &str) -> bool {
bin_dir_in(path, "tmux").is_some()
}
pub(crate) fn tmux_available() -> bool {
std::env::var("PATH")
.ok()
.is_some_and(|path| tmux_available_in(&path))
}
pub(crate) fn agent_command_available_in(path: &str, command: &str) -> bool {
bin_dir_in(path, command).is_some()
}
pub(crate) fn agent_command_available(command: &str) -> bool {
std::env::var("PATH")
.ok()
.is_some_and(|path| agent_command_available_in(&path, command))
}
pub(crate) fn tmux_fallback_dirs(home: &str) -> Vec<String> {
vec![
"/opt/homebrew/bin".to_string(),
"/usr/local/bin".to_string(),
format!("{home}/.local/bin"),
]
}
pub(crate) fn resolve_tmux_bin_from(path: &str, fallback_dirs: &[String]) -> String {
if let Some(dir) = bin_dir_in(path, "tmux") {
return format!("{dir}/tmux");
}
for dir in fallback_dirs {
if std::path::Path::new(dir).join("tmux").is_file() {
return format!("{dir}/tmux");
}
}
"tmux".to_string()
}
pub(crate) fn resolve_tmux_bin() -> String {
let home = std::env::var("HOME").unwrap_or_else(|_| "/root".to_string());
let path = std::env::var("PATH").unwrap_or_default();
resolve_tmux_bin_from(&path, &tmux_fallback_dirs(&home))
}
pub(crate) fn cron_path(agent_command: &str) -> String {
let home = std::env::var("HOME").unwrap_or_else(|_| "/root".to_string());
let mut dirs: Vec<String> = Vec::new();
for bin in ["tmux", agent_command] {
if let Some(dir) = bin_dir(bin) {
dirs.push(dir);
}
}
for dir in [
format!("{home}/.local/bin"),
"/opt/homebrew/bin".to_string(),
"/usr/local/bin".to_string(),
format!("{home}/.cargo/bin"),
format!("{home}/.bun/bin"),
"/usr/bin".to_string(),
"/bin".to_string(),
"/usr/sbin".to_string(),
"/sbin".to_string(),
] {
dirs.push(dir);
}
let mut seen = std::collections::HashSet::new();
dirs.retain(|dir| seen.insert(dir.clone()));
dirs.join(":")
}