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
@@ -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)@@ -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()) }