use anyhow::{Context, Result};
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::{fs, path::PathBuf};
pub fn make_executable(exec_path: &Path) -> Result<()> {
if !exec_path.exists() {
anyhow::bail!("Invalid executable path: {}", exec_path.to_string_lossy());
}
match fs::metadata(exec_path) {
Ok(metadata) => {
let mut permissions = metadata.permissions();
let mode = permissions.mode();
permissions.set_mode(mode | 0o111);
fs::set_permissions(exec_path, permissions)
.context("Failed to set executable permissions")?;
}
Err(e) => {
return Err(e).context("Failed to read metadata");
}
}
Ok(())
}
pub fn find_executable(directory_path: &Path, name: &str) -> Option<PathBuf> {
let bin_path = directory_path.join("bin").join(name);
if bin_path.is_file() {
return Some(bin_path);
}
let direct_path = directory_path.join(name);
if direct_path.is_file() {
return Some(direct_path);
}
if let Some(dir_name) = directory_path.file_name() {
let derived_path = directory_path.join(dir_name);
if derived_path.is_file() {
return Some(derived_path);
}
}
if let Ok(entries) = fs::read_dir(directory_path) {
for entry in entries.flatten() {
if let Ok(file_type) = entry.file_type()
&& file_type.is_file()
&& let Some(file_name) = entry.file_name().to_str()
&& file_name.to_lowercase().starts_with(&name.to_lowercase())
{
return Some(entry.path());
}
}
}
None
}