fix: Prioritize Homebrew paths over Linux paths in PATH search

Previous version returned the first match found in PATH, which meant
/usr/local/bin would be chosen before /opt/homebrew/bin if it appeared
first in the PATH variable.

Changes:
- Collect ALL candidate paths from PATH first
- Assign priority scores (1=Homebrew, 2=.local, 3=.cargo, 4=/usr/local, 5=/usr/bin)
- Sort by priority (lowest number = highest priority)
- Return the highest priority path

This ensures macOS Homebrew paths (/opt/homebrew/bin) are always
preferred over Linux/Intel Mac paths (/usr/local/bin), regardless
of PATH order.

Priority scheme:
1. /opt/homebrew/bin (M1/M2/M3/M4 Macs with Homebrew)
2. ~/.local/bin (user-local installs)
3. ~/.cargo/bin (Rust/Cargo installs)
4. /usr/local/bin (Linux/Intel Mac standard)
5. /usr/bin (system binaries)
This commit is contained in:
2025-11-10 20:46:11 -07:00
parent be63fe17e2
commit 1ec1ef5def

View File

@@ -281,23 +281,37 @@ fn resolve_binary_path(explicit_path: &Option<String>) -> Result<String> {
if let Ok(path_env) = std::env::var("PATH") {
let binary_names = ["gitea-mcp", "gitea-mcp-server"];
// Parse PATH and try each directory with each binary name
// Collect all candidate paths from PATH, then prioritize them
let mut candidates = Vec::new();
// Parse PATH and collect all plausible paths
for path_dir in path_env.split(':') {
for binary_name in &binary_names {
let full_path = format!("{}/{}", path_dir, binary_name);
// We can't check if file exists in WASM, but we can return the path
// and let Zed try to execute it. We'll return the first match from
// common directories to increase success rate.
if path_dir.contains("/usr/local/bin")
|| path_dir.contains("/usr/bin")
|| path_dir.contains("/opt/homebrew/bin")
|| path_dir.contains("/.local/bin")
|| path_dir.contains("/.cargo/bin")
{
// This looks like a plausible location, try it
return Ok(full_path);
// Categorize by priority (lower number = higher priority)
let priority = if path_dir.contains("/opt/homebrew/bin") {
1 // Highest: macOS Homebrew (M1/M2/M3/M4 Macs)
} else if path_dir.contains("/.local/bin") {
2 // User-local installations
} else if path_dir.contains("/.cargo/bin") {
3 // Cargo installations
} else if path_dir.contains("/usr/local/bin") {
4 // Linux standard location
} else if path_dir.contains("/usr/bin") {
5 // System binaries
} else {
continue; // Skip non-standard locations
};
candidates.push((priority, full_path));
}
}
// Sort by priority and return the highest priority candidate
candidates.sort_by_key(|(priority, _)| *priority);
if let Some((_, path)) = candidates.first() {
return Ok(path.clone());
}
}