diff --git a/src/mcp_server_gitea.rs b/src/mcp_server_gitea.rs index e343997..7905d6d 100644 --- a/src/mcp_server_gitea.rs +++ b/src/mcp_server_gitea.rs @@ -250,128 +250,80 @@ fn find_docker_binary() -> Result { /// Resolve the gitea-mcp binary path with intelligent fallbacks /// /// Resolution strategy: -/// 1. If explicit path provided in settings, try it and also fall back to searches -/// 2. Try common system paths: -/// - /usr/local/bin/gitea-mcp -/// - ~/.local/bin/gitea-mcp -/// - ~/.cargo/bin/gitea-mcp -/// - /opt/homebrew/bin/gitea-mcp (macOS M-series) +/// 1. If explicit path provided in settings, use it directly +/// 2. Try each standard path in order (macOS Homebrew paths first on macOS) /// 3. Search in PATH environment variable -/// 4. If no path works, return just the binary name (let system PATH handle it) +/// 4. Return "gitea-mcp" as last resort (let system PATH find it) /// -/// Returns the path to the binary (as a string) to use, or an error if all options fail +/// Note: Since WASM sandbox may restrict exists() checks, we return the first +/// path in the search order that we reach. This relies on the order being correct. +/// +/// Returns the path to the binary (as a string) to use fn resolve_binary_path(explicit_path: &Option) -> Result { // If explicit path provided, use it (prioritize user configuration) - // WASM sandbox may restrict exists() checks, so we return it even if exists() fails if let Some(path) = explicit_path { return Ok(path.clone()); } - // Build list of common binary paths to try + // Build list of common binary paths to try IN ORDER // Note: On macOS, Homebrew paths are checked first since that's the recommended // installation method and Homebrew installs as 'gitea-mcp-server' - let mut search_paths = vec![]; - // macOS M-series (ARM64) Homebrew locations - check first on macOS + // macOS M-series (ARM64) Homebrew locations - highest priority on macOS #[cfg(target_os = "macos")] { - search_paths.push(PathBuf::from("/opt/homebrew/bin/gitea-mcp")); - search_paths.push(PathBuf::from("/opt/homebrew/bin/gitea-mcp-server")); + // On macOS, return Homebrew path directly without checking exists() + // since WASM sandbox restricts filesystem access + return Ok("/opt/homebrew/bin/gitea-mcp-server".to_string()); } - // Standard system paths (work on Linux, macOS, Windows) - search_paths.push(PathBuf::from("/usr/local/bin/gitea-mcp")); - search_paths.push(PathBuf::from("/usr/local/bin/gitea-mcp-server")); - search_paths.push(PathBuf::from("/usr/bin/gitea-mcp")); - search_paths.push(PathBuf::from("/usr/bin/gitea-mcp-server")); - - // Add home directory paths - if let Ok(home) = std::env::var("HOME") { - search_paths.push(PathBuf::from(&home).join(".local/bin/gitea-mcp")); - search_paths.push(PathBuf::from(&home).join(".local/bin/gitea-mcp-server")); - search_paths.push(PathBuf::from(&home).join("bin/gitea-mcp")); - search_paths.push(PathBuf::from(&home).join("bin/gitea-mcp-server")); - search_paths.push(PathBuf::from(&home).join(".cargo/bin/gitea-mcp")); - search_paths.push(PathBuf::from(&home).join(".cargo/bin/gitea-mcp-server")); - } - - // Windows locations - #[cfg(target_os = "windows")] + // Non-macOS systems: try standard locations and PATH + #[cfg(not(target_os = "macos"))] { - if let Ok(program_files) = std::env::var("PROGRAMFILES") { - search_paths.push(PathBuf::from(&program_files).join("gitea-mcp\\gitea-mcp.exe")); - } - if let Ok(program_files_x86) = std::env::var("PROGRAMFILES(x86)") { - search_paths.push(PathBuf::from(&program_files_x86).join("gitea-mcp\\gitea-mcp.exe")); - } - search_paths.push(PathBuf::from("C:\\Program Files\\gitea-mcp\\gitea-mcp.exe")); - search_paths.push(PathBuf::from( - "C:\\Program Files (x86)\\gitea-mcp\\gitea-mcp.exe", - )); - } + let mut all_paths = vec![ + "/usr/local/bin/gitea-mcp".to_string(), + "/usr/local/bin/gitea-mcp-server".to_string(), + "/usr/bin/gitea-mcp".to_string(), + "/usr/bin/gitea-mcp-server".to_string(), + ]; - // Check each default path - prioritize paths that actually exist - let mut fallback_path: Option = None; - - for path in &search_paths { - // Try exists() - may not work in WASM but worth trying - if path.exists() { - return Ok(path.display().to_string()); + // Add home directory paths + if let Ok(home) = std::env::var("HOME") { + all_paths.push(format!("{}/.local/bin/gitea-mcp", home)); + all_paths.push(format!("{}/.local/bin/gitea-mcp-server", home)); + all_paths.push(format!("{}/bin/gitea-mcp", home)); + all_paths.push(format!("{}/bin/gitea-mcp-server", home)); + all_paths.push(format!("{}/.cargo/bin/gitea-mcp", home)); + all_paths.push(format!("{}/.cargo/bin/gitea-mcp-server", home)); } - // Store first absolute path as fallback in case exists() is restricted by WASM - if fallback_path.is_none() { - let path_str = path.display().to_string(); - if path.is_absolute() && !path_str.is_empty() { - fallback_path = Some(path_str); + + // Try each path in order + for path in &all_paths { + if PathBuf::from(path).exists() { + return Ok(path.to_string()); } } - } - // Return fallback if no path existed - if let Some(path) = fallback_path { - return Ok(path); - } - - // Try to find in PATH environment variable - if let Ok(path_env) = std::env::var("PATH") { - let separator = if cfg!(target_os = "windows") { - ";" - } else { - ":" - }; - for path_dir in path_env.split(separator) { - // Try both gitea-mcp and gitea-mcp-server names - let binary_names = if cfg!(target_os = "windows") { - vec!["gitea-mcp.exe", "gitea-mcp-server.exe"] + // Try to find in PATH environment variable + if let Ok(path_env) = std::env::var("PATH") { + let separator = if cfg!(target_os = "windows") { + ";" } else { - vec!["gitea-mcp", "gitea-mcp-server"] + ":" }; - - for binary_name in binary_names { - let binary_path = PathBuf::from(path_dir).join(binary_name); - if binary_path.exists() { - return Ok(binary_path.display().to_string()); - } - // Also try returning PATH entry even if exists() fails (WASM sandbox) - if !path_dir.is_empty() { - let full_path = PathBuf::from(path_dir).join(binary_name); - return Ok(full_path.display().to_string()); + for path_dir in path_env.split(separator) { + for binary_name in &["gitea-mcp", "gitea-mcp-server"] { + let binary_path = PathBuf::from(path_dir).join(binary_name); + if binary_path.exists() { + return Ok(binary_path.display().to_string()); + } } } } + + // Last resort: return gitea-mcp and let system find it via PATH + return Ok("gitea-mcp".to_string()); } - - // Last resort: try just the binary name and let the system find it - // This handles cases where filesystem checks fail in WASM sandbox - let binary_name = if cfg!(target_os = "windows") { - "gitea-mcp.exe" - } else { - "gitea-mcp" - }; - - // If we got here, we couldn't find it in standard paths - // Try the binary name directly - system PATH will resolve it - Ok(binary_name.to_string()) } // Register the extension with Zed