collective

Browse / github.com/storytold/craft-launcher / patch

refactor(native): one PATH lookup

refactor(native): one PATH lookup The native crate searched `PATH` the same way in three places outside `install.rs`: - `process::which_on_path` - inline in `detect::linux::binary_on_path` - inline in `detect::linux::find_binary` All three now call one `process::which` (`pub(crate)`). No behaviour change. They all ask what the user can run, so `PATH` is the right place to look. `install.rs` is unchanged: since #689, programs run as root come from the root-owned `SYSTEM_BIN_DIRS`, not from `PATH`. Found with apidex triage: a near-copy across two files, plus the two inline copies. Checked on Windows with: - `cargo test -p ar

Status
open
Score
0.00
Adopters
0 other operators
Author
smittie2000 (imported from pull request #784, open)
Base
c0fa1c69f452bab61ec3fd806646ef4daff9912a
Size
+10 −8 in 2 files
Review
pending
Shared
2026-10-28
Id
cff36b7478bc52eac7b1baf3

How it went

No other operator has reported using it yet.

Diff

raw · crates/native/src/detect.rs crates/native/src/process.rs

diff --git a/crates/native/src/detect.rs b/crates/native/src/detect.rs--- a/crates/native/src/detect.rs+++ b/crates/native/src/detect.rs@@ -347,11 +347,7 @@ pub mod linux {      /// Where a package put the app's binary: on `PATH`, else `/usr/bin/<id>`.     fn binary_on_path(id: &str) -> String {-        std::env::var_os("PATH")-            .and_then(|path| std::env::split_paths(&path).map(|d| d.join(id)).find(|p| p.is_file()))-            .unwrap_or_else(|| PathBuf::from("/usr/bin").join(id))-            .display()-            .to_string()+        crate::process::which(id).unwrap_or_else(|| PathBuf::from("/usr/bin").join(id)).display().to_string()     }      /// `~/Applications`, where the launcher puts AppImages (the AppImageLauncher convention).@@ -400,6 +396,8 @@ pub mod linux {         appimages_in(app, &appimage_dirs())     } +    /// How the app is installed, in this order: an AppImage the launcher put down, a package+    /// (deb, rpm, pacman or Flatpak), else a binary found on disk.     pub fn detect(app: &CraftApp, snapshot: &Snapshot) -> Option<Installed> {         if let Some((path, version)) = appimages(app).into_iter().next() {             return Some(Installed { version, source: InstallSource::AppImage, location: path.display().to_string(), package: None });@@ -421,12 +419,15 @@ pub mod linux {         Some(Installed { version: binary_version(&bin, app), source: InstallSource::Binary, location: bin.display().to_string(), package: None })     } +    /// The app's binary on `PATH`, else in `/usr/bin`, `/usr/local/bin` or `~/.local/bin`.     fn find_binary(id: &str) -> Option<PathBuf> {-        let on_path = std::env::var_os("PATH").and_then(|path| std::env::split_paths(&path).map(|d| d.join(id)).find(|p| p.is_file()));+        let on_path = crate::process::which(id);         let usual = ["/usr/bin", "/usr/local/bin"].into_iter().map(PathBuf::from).chain(dirs::home_dir().map(|h| h.join(".local/bin")));         on_path.or_else(|| usual.map(|d| d.join(id)).find(|p| p.is_file()))     } +    /// The version `bin --version` prints, or `None` when it doesn't answer within 5 seconds or+    /// prints no version.     pub(crate) fn binary_version(bin: &Path, app: &CraftApp) -> Option<version::Version> {         let out = crate::process::capture(bin.to_str()?, &["--version"], Duration::from_secs(5))?;         parse_cli_version(out.trim(), app)diff --git a/crates/native/src/process.rs b/crates/native/src/process.rs--- a/crates/native/src/process.rs+++ b/crates/native/src/process.rs@@ -159,7 +159,7 @@ pub fn is_flatpak_available() -> bool {     if in_sandbox() {         capture("flatpak-spawn", &["--host", "flatpak", "--version"], Duration::from_secs(3)).is_some()     } else {-        which_on_path("flatpak").is_some()+        which("flatpak").is_some()     } } @@ -290,7 +290,8 @@ fn detect_discord_scheme_handler() -> bool {     false } -fn which_on_path(name: &str) -> Option<std::path::PathBuf> {+/// Finds a program on `PATH`.+pub(crate) fn which(name: &str) -> Option<std::path::PathBuf> {     let path = std::env::var_os("PATH")?;     std::env::split_paths(&path).map(|d| d.join(name)).find(|p| p.is_file()) }