mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
fix(tauri): skip deep-link register_all when xdg-mime is missing (OPENHUMAN-TAURI-AS) (#1766)
This commit is contained in:
+121
-1
@@ -775,6 +775,26 @@ fn is_daemon_mode() -> bool {
|
||||
std::env::args().any(|arg| arg == "daemon" || arg == "--daemon")
|
||||
}
|
||||
|
||||
/// Returns true when an executable named `name` is discoverable on `$PATH`.
|
||||
///
|
||||
/// Inline `which`-style lookup so the deep-link pre-flight on Linux can
|
||||
/// skip `tauri-plugin-deep-link::register_all` cleanly when `xdg-mime` is
|
||||
/// missing (OPENHUMAN-TAURI-AS). Walks `$PATH` entries, joins `name`, and
|
||||
/// returns true on the first hit that is a regular file. The metadata check
|
||||
/// is `is_file()` rather than an executable-bit check: on Linux any file in
|
||||
/// `$PATH` that is named like the binary is enough to gate the plugin call
|
||||
/// (the plugin itself will surface the real exec error to its own warn),
|
||||
/// and an executable-bit check would require unix-specific
|
||||
/// `MetadataExt::mode` plumbing that isn't worth the platform branch for a
|
||||
/// single discoverability gate.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn path_has_executable(name: &str) -> bool {
|
||||
let Some(path_var) = std::env::var_os("PATH") else {
|
||||
return false;
|
||||
};
|
||||
std::env::split_paths(&path_var).any(|dir| dir.join(name).is_file())
|
||||
}
|
||||
|
||||
/// Tauri command: bring the main window to front from any webview (e.g. overlay orb click).
|
||||
#[tauri::command]
|
||||
fn activate_main_window(app: AppHandle<AppRuntime>) -> Result<(), String> {
|
||||
@@ -1723,12 +1743,40 @@ pub fn run() {
|
||||
let builder = builder.manage(meet_video::frame_bus::MeetVideoFrameBusState::new());
|
||||
builder
|
||||
.setup(move |app| {
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let Err(err) = app.deep_link().register_all() {
|
||||
log::warn!("[deep-link] register_all failed (non-fatal): {err}");
|
||||
}
|
||||
}
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
// `tauri-plugin-deep-link::register_all` on Linux shells out
|
||||
// to `xdg-mime` (and `update-desktop-database` / `xdg-icon-resource`)
|
||||
// to install MIME-type associations for our custom URL
|
||||
// schemes. On Linux installs that ship without xdg-utils —
|
||||
// WSL2 without a desktop env, headless servers, minimal
|
||||
// containers (OPENHUMAN-TAURI-AS: WSL2 user in BR) — the
|
||||
// tool isn't on PATH and the plugin fires
|
||||
// `log::error!("Failed to run OS command \`xdg-mime\`…")`
|
||||
// *internally* before returning the Err. That internal
|
||||
// error log is scooped up by `sentry-tracing` into a Sentry
|
||||
// event even though our `if let Err` arm below already
|
||||
// demotes the user-visible failure to a warn. Skip the
|
||||
// plugin call entirely when xdg-mime isn't available so
|
||||
// the internal log never fires — registration only matters
|
||||
// on systems with a desktop environment, where xdg-utils
|
||||
// is part of the desktop install anyway.
|
||||
if path_has_executable("xdg-mime") {
|
||||
if let Err(err) = app.deep_link().register_all() {
|
||||
log::warn!("[deep-link] register_all failed (non-fatal): {err}");
|
||||
}
|
||||
} else {
|
||||
log::warn!(
|
||||
"[deep-link] skipping register_all — xdg-mime not on PATH (xdg-utils not installed; deep-link MIME registration unavailable on this host)"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the webview_apis WebSocket bridge BEFORE spawning core —
|
||||
// core reads OPENHUMAN_WEBVIEW_APIS_PORT on first connect, and
|
||||
@@ -3048,4 +3096,76 @@ mod tests {
|
||||
"messages that merely contain the dev-proxy prefix must NOT be filtered"
|
||||
);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// path_has_executable / deep-link xdg-mime pre-flight (OPENHUMAN-TAURI-AS)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/// With a controlled `$PATH` containing one dir that holds a file named
|
||||
/// `xdg-mime`, the lookup must succeed (mirrors a Linux desktop install
|
||||
/// where xdg-utils ships the binary).
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn path_has_executable_finds_file_on_path() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let original = std::env::var_os("PATH");
|
||||
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
std::fs::write(dir.path().join("xdg-mime"), b"#!/bin/sh\n").expect("write stub");
|
||||
std::env::set_var("PATH", dir.path());
|
||||
|
||||
assert!(
|
||||
path_has_executable("xdg-mime"),
|
||||
"must discover xdg-mime when present in a $PATH entry"
|
||||
);
|
||||
|
||||
match original {
|
||||
Some(v) => std::env::set_var("PATH", v),
|
||||
None => std::env::remove_var("PATH"),
|
||||
}
|
||||
}
|
||||
|
||||
/// With a controlled `$PATH` that does NOT contain `xdg-mime`, the lookup
|
||||
/// must fail (mirrors WSL2 / minimal containers without xdg-utils — the
|
||||
/// case OPENHUMAN-TAURI-AS protects against).
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn path_has_executable_returns_false_when_missing() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let original = std::env::var_os("PATH");
|
||||
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
// Intentionally do not create xdg-mime in `dir`.
|
||||
std::env::set_var("PATH", dir.path());
|
||||
|
||||
assert!(
|
||||
!path_has_executable("xdg-mime"),
|
||||
"must return false when xdg-mime is not in any $PATH entry"
|
||||
);
|
||||
|
||||
match original {
|
||||
Some(v) => std::env::set_var("PATH", v),
|
||||
None => std::env::remove_var("PATH"),
|
||||
}
|
||||
}
|
||||
|
||||
/// When `$PATH` is unset entirely, the lookup must short-circuit to false
|
||||
/// rather than panic or fall back to the cwd.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn path_has_executable_returns_false_when_path_unset() {
|
||||
let _g = ENV_LOCK.lock().unwrap();
|
||||
let original = std::env::var_os("PATH");
|
||||
|
||||
std::env::remove_var("PATH");
|
||||
assert!(
|
||||
!path_has_executable("xdg-mime"),
|
||||
"unset $PATH must yield false (skip register_all on the missing-xdg-utils branch)"
|
||||
);
|
||||
|
||||
match original {
|
||||
Some(v) => std::env::set_var("PATH", v),
|
||||
None => std::env::remove_var("PATH"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user