diff options
Diffstat (limited to 'libs/nak/src/runtime_wrap.rs')
| -rw-r--r-- | libs/nak/src/runtime_wrap.rs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/libs/nak/src/runtime_wrap.rs b/libs/nak/src/runtime_wrap.rs new file mode 100644 index 0000000..d33bd59 --- /dev/null +++ b/libs/nak/src/runtime_wrap.rs @@ -0,0 +1,121 @@ +use std::env; +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; +use std::process::Command; + +fn env_flag(name: &str) -> bool { + matches!( + env::var(name) + .unwrap_or_default() + .trim() + .to_ascii_lowercase() + .as_str(), + "1" | "true" | "yes" | "on" + ) +} + +pub fn use_steam_run() -> bool { + env_flag("NAK_USE_STEAM_RUN") +} + +pub fn use_umu_for_prefix() -> bool { + env_flag("NAK_USE_UMU_FOR_PREFIX") +} + +pub fn prefer_system_umu() -> bool { + env_flag("NAK_PREFER_SYSTEM_UMU") +} + +fn find_in_path(binary: &str) -> Option<PathBuf> { + let path = env::var_os("PATH")?; + env::split_paths(&path) + .map(|entry| entry.join(binary)) + .find(|candidate| candidate.exists()) +} + +pub fn resolve_umu_run() -> Option<PathBuf> { + if is_flatpak() { + // In Flatpak, umu-run must run on the host via flatpak-spawn --host. + let host_copy = env::var("XDG_DATA_HOME") + .ok() + .map(PathBuf::from) + .unwrap_or_else(|| { + let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string()); + PathBuf::from(home).join(".local/share") + }) + .join("fluorine/umu-run"); + if host_copy.exists() { + return Some(host_copy); + } + // Fall back to bare name for host PATH resolution. + return Some(PathBuf::from("umu-run")); + } + + let bundled = env::var("NAK_BUNDLED_UMU_RUN") + .ok() + .map(PathBuf::from) + .filter(|p| p.exists()); + let system = find_in_path("umu-run"); + + if prefer_system_umu() { + system.or(bundled) + } else { + bundled.or(system) + } +} + +pub fn is_flatpak() -> bool { + Path::new("/.flatpak-info").exists() +} + +/// Build a command to run `exe` with the given environment variables. +/// +/// In Flatpak mode, `flatpak-spawn --host` is used and env vars are passed as +/// `--env=KEY=VALUE` flags (the host process does NOT inherit the sandbox env). +/// In steam-run mode, the command is wrapped with `steam-run`. +/// Otherwise the command runs directly. +pub fn build_command<S: AsRef<OsStr>>( + exe: impl AsRef<OsStr>, + envs: &[(&str, S)], +) -> Command { + if use_steam_run() { + let mut cmd = Command::new("steam-run"); + cmd.arg(exe.as_ref()); + for (key, value) in envs { + cmd.env(key, value.as_ref()); + } + return cmd; + } + if is_flatpak() { + let mut cmd = Command::new("flatpak-spawn"); + cmd.arg("--host"); + for (key, value) in envs { + cmd.arg(format!( + "--env={}={}", + key, + value.as_ref().to_string_lossy() + )); + } + cmd.arg(exe.as_ref()); + return cmd; + } + let mut cmd = Command::new(exe); + for (key, value) in envs { + cmd.env(key, value.as_ref()); + } + cmd +} + +/// Build a command with no extra environment variables. +pub fn command_for(exe: impl AsRef<OsStr>) -> Command { + build_command::<&str>(exe, &[]) +} + +pub fn bundled_umu_path_from_appdir(appdir: &Path) -> Option<PathBuf> { + let path = appdir.join("umu-run"); + if path.exists() { + Some(path) + } else { + None + } +} |
