upstream_rs/services/integration/
permission_handler.rs1use anyhow::{Context, Result};
2
3#[cfg(unix)]
4use std::os::unix::fs::PermissionsExt;
5
6use std::path::Path;
7use std::{fs, path::PathBuf};
8
9#[cfg(unix)]
11pub fn make_executable(exec_path: &Path) -> Result<()> {
12 if !exec_path.exists() {
13 anyhow::bail!("Invalid executable path: {}", exec_path.to_string_lossy());
14 }
15
16 match fs::metadata(exec_path) {
17 Ok(metadata) => {
18 let mut permissions = metadata.permissions();
19 let mode = permissions.mode();
20
21 permissions.set_mode(mode | 0o111);
22
23 fs::set_permissions(exec_path, permissions)
24 .context("Failed to set executable permissions")?;
25 }
26 Err(e) => {
27 return Err(e).context("Failed to read metadata");
28 }
29 }
30
31 Ok(())
32}
33
34#[cfg(windows)]
35pub fn make_executable(exec_path: &Path) -> Result<()> {
36 Ok(())
37}
38
39pub fn find_executable(directory_path: &Path, name: &str) -> Option<PathBuf> {
41 #[cfg(windows)]
42 let name = &format!("{}.exe", name);
43
44 let bin_path = directory_path.join("bin").join(name);
46 if bin_path.is_file() {
47 return Some(bin_path);
48 }
49
50 let direct_path = directory_path.join(name);
52 if direct_path.is_file() {
53 return Some(direct_path);
54 }
55
56 if let Some(dir_name) = directory_path.file_name() {
59 let derived_path = directory_path.join(dir_name);
60 if derived_path.is_file() {
61 return Some(derived_path);
62 }
63 }
64
65 if let Ok(entries) = fs::read_dir(directory_path) {
68 for entry in entries.flatten() {
69 if let Ok(file_type) = entry.file_type()
70 && file_type.is_file()
71 && let Some(file_name) = entry.file_name().to_str()
72 && file_name.to_lowercase().starts_with(&name.to_lowercase())
73 {
74 return Some(entry.path());
75 }
76 }
77 }
78
79 None
80}