1use std::borrow::Cow;
2use std::env;
3use std::path::{Path, PathBuf};
4
5#[inline]
6#[must_use]
7pub const fn is_appimage_build() -> bool {
8    match option_env!("JGENESIS_APPIMAGE_BUILD") {
9        Some(var) => !var.is_empty(),
10        None => false,
11    }
12}

Fix relative input paths when running from inside an AppImage.

The AppImage runner changes the current working directory to a subdirectory inside the AppImage package, which leads to very confusing behavior if a user passes a relative path as input. This function prefixes relative paths with the working directory that the AppImage was launched from.

Returns the input path untouched if the input path is absolute or this is not an AppImage build.

21#[inline]
22#[must_use]
23pub fn fix_appimage_relative_path(path: &Path) -> Cow<'_, Path> {
24    if !is_appimage_build() || path.is_absolute() {
25        return path.into();
26    }
27
28    let Ok(owd) = env::var("OWD") else { return path.into() };
29    let converted = Path::new(&owd).join(path);
30
31    log::info!(
32        "Converted relative path '{}' to absolute path '{}'",
33        path.display(),
34        converted.display()
35    );
36
37    converted.into()
38}

Directory containing the emulator executable

Returns None if unable to determine

43#[inline]
44#[must_use]
45pub fn determine_emulator_dir() -> Option<PathBuf> {
46    let exe_path: PathBuf = if is_appimage_build() {
47        // When running from inside an AppImage, env::current_exe() returns a path inside the mount's
48        // temp dir.
49        //
50        // APPIMAGE env var should contain the path to the AppImage file:
51        //    https://docs.appimage.org/packaging-guide/environment-variables.html
52        env::var("APPIMAGE").ok()?.into()
53    } else {
54        env::current_exe().ok()?
55    };
56
57    exe_path.parent().map(ToOwned::to_owned)
58}