Browse / github.com/storytold/craft-launcher / patch
Linux: detect versions of renamed AppImages (#471)
launcher does not seem to be able to detect versions in AppImage nor suggest update I have 0.7.0 photocraft as indicated by gear level (reload meta data button) <img width="1418" height="1127" alt="Image" src="https://github.com/user-attachments/assets/076a04e1-65ba-4175-8cdf-4dab322d7272" /> the latest is 0.9.0, but the launcher thinks i'm on the latest <img width="2379" height="1576" alt="Image" src="https://github.com/user-attachments/assets/a1b21c6d-a961-4f32-9172-5e4daeb330ca" /> both photocraft and launcher were app image note: the flatpak launcher is also have the same issue with app image photocraft.
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- FredApps (imported from pull request #499, open)
- Base
3fd2d56999fa00a7b90f159cb686a5fc64347e7e- Size
- +59 −1 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
b5312a6d96d06451eb8a1583
How it went
No other operator has reported using it yet.
Diff
raw · crates/native/src/detect.rs
@@ -374,7 +374,12 @@ pub mod linux { 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 });+ return Some(appimage_install(app, path, version, |bin, app| {+ let (program, args) = appimage_probe_command(bin, crate::process::in_sandbox())?;+ let args: Vec<&str> = args.iter().map(String::as_str).collect();+ let out = crate::process::capture(&program, &args, Duration::from_secs(5))?;+ parse_cli_version(out.trim(), app)+ })); } let order = [InstallSource::Deb, InstallSource::Rpm, InstallSource::Pacman, InstallSource::Flatpak]; if let Some(p) = packages::find(app, &snapshot.packages, &order) {@@ -384,6 +389,25 @@ pub mod linux { detect_system_install(app) } + /// Bare AppImage names (for example Gear Lever's rename) carry no version (#471).+ /// Probe only the selected unknown-version app; release filenames need no execution.+ pub(crate) fn appimage_install(+ app: &CraftApp,+ path: PathBuf,+ version: Option<version::Version>,+ probe: impl FnOnce(&Path, &CraftApp) -> Option<version::Version>,+ ) -> Installed {+ let version = version.or_else(|| probe(&path, app));+ Installed { version, source: InstallSource::AppImage, location: path.display().to_string(), package: None }+ }++ /// A host AppImage must be queried on the host when the launcher runs inside Flatpak,+ /// just as launching it is. Paths remain individual arguments, never shell commands.+ pub(crate) fn appimage_probe_command(bin: &Path, sandbox: bool) -> Option<(String, Vec<String>)> {+ let path = bin.to_str()?.to_string();+ Some(if sandbox { ("flatpak-spawn".into(), vec!["--host".into(), path, "--version".into()]) } else { (path, vec!["--version".into()]) })+ }+ /// When the package managers don't report the app (a query timed out or was locked, an /// unlisted package name, or a sandbox that can't see them) but its binary is there. It is /// reported as a system binary: the launcher can open it but leaves updating and removing it@@ -431,6 +455,40 @@ pub mod freebsd { mod linux_tests { use super::*; + #[test]+ fn renamed_appimage_reports_its_cli_version_and_offers_the_update() {+ use artcraft_launcher_core::status::{AppStatus, Latest, status};+ let app = CraftApp::by_id("photocraft").unwrap();+ let installed = linux::appimage_install(app, PathBuf::from("/tmp/My Apps/photocraft.appimage"), None, |_, app| {+ parse_cli_version("photocraft 0.7.0 (792616159, 2026-10-11)", app)+ });+ let latest = version::parse("0.9.0").unwrap();+ assert_eq!(installed.version.as_ref().unwrap().to_string(), "0.7.0");+ assert_eq!(status(Some(&installed), Latest::Found { version: Some(&latest), has_asset: true }), AppStatus::UpdateAvailable);+ }++ #[test]+ fn known_appimage_versions_skip_the_probe_and_failed_probes_stay_unknown() {+ let app = CraftApp::by_id("photocraft").unwrap();+ let known = linux::appimage_install(app, PathBuf::from("photocraft-0.7.0-linux-x86_64.AppImage"), version::parse("0.7.0"), |_, _| {+ panic!("release filename already gives the version")+ });+ assert_eq!(known.version.unwrap().to_string(), "0.7.0");+ let unknown = linux::appimage_install(app, PathBuf::from("photocraft.appimage"), None, |_, _| None);+ assert!(unknown.version.is_none());+ assert_eq!(unknown.source, InstallSource::AppImage);+ }++ #[test]+ fn appimage_version_probe_uses_host_arguments_in_flatpak() {+ let path = Path::new("/home/user/My Apps/photo;craft.appimage");+ assert_eq!(linux::appimage_probe_command(path, false), Some((path.display().to_string(), vec!["--version".into()])));+ assert_eq!(+ linux::appimage_probe_command(path, true),+ Some(("flatpak-spawn".into(), vec!["--host".into(), path.display().to_string(), "--version".into()]))+ );+ }+ #[test] fn ours_filter_matches_rpm_packages() { let ours = |name: &str| {