uv/crates/uv-python/src/which.rs
konsti 7beae77283
Search for all python3.x in PATH (#5148)
Search for all `python3.x` minor versions in PATH, skipping those we
already know we can use.

For example, let's say `python` and `python3` are Python 3.10. When a
user requests `>= 3.11`, we still need to find a `python3.12` in PATH.
We do so with a regex matcher.

Fixes #4709
2024-07-18 17:00:01 +02:00

40 lines
1 KiB
Rust

use std::path::Path;
/// Check whether a path in PATH is a valid executable.
///
/// Derived from `which`'s `Checker`.
pub(crate) fn is_executable(path: &Path) -> bool {
#[cfg(any(unix, target_os = "wasi", target_os = "redox"))]
{
if rustix::fs::access(path, rustix::fs::Access::EXEC_OK).is_err() {
return false;
}
}
#[cfg(target_os = "windows")]
{
let Ok(file_type) = fs_err::symlink_metadata(path).map(|metadata| metadata.file_type())
else {
return false;
};
if !file_type.is_file() && !file_type.is_symlink() {
return false;
}
if path.extension().is_none()
&& winsafe::GetBinaryType(&path.display().to_string()).is_err()
{
return false;
}
}
if cfg!(not(target_os = "windows")) {
if !fs_err::metadata(path)
.map(|metadata| metadata.is_file())
.unwrap_or(false)
{
return false;
}
}
true
}