From 2f59d900fbd82957505b5e567d267cb13f3564da Mon Sep 17 00:00:00 2001 From: Kwensiu Date: Thu, 16 Apr 2026 00:45:15 +0800 Subject: [PATCH] fix(windows): improve fnm Node path discovery --- src-tauri/src/bin/codeg_server.rs | 1 + src-tauri/src/process.rs | 22 ++++++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/bin/codeg_server.rs b/src-tauri/src/bin/codeg_server.rs index e4294f04..706ea6bd 100644 --- a/src-tauri/src/bin/codeg_server.rs +++ b/src-tauri/src/bin/codeg_server.rs @@ -16,6 +16,7 @@ async fn main() { return; } + codeg_lib::process::ensure_node_in_path(); codeg_lib::process::ensure_user_npm_prefix_in_path(); let port: u16 = std::env::var("CODEG_PORT") diff --git a/src-tauri/src/process.rs b/src-tauri/src/process.rs index 3fab9a8c..aff86847 100644 --- a/src-tauri/src/process.rs +++ b/src-tauri/src/process.rs @@ -125,7 +125,6 @@ where /// child processes) can find node/npm/npx without any special handling. /// /// Call once at startup, after `fix_path_env::fix()`. -#[cfg(feature = "tauri-runtime")] pub fn ensure_node_in_path() { // Already reachable — nothing to do. if which::which("node").is_ok() { @@ -145,7 +144,6 @@ pub fn ensure_node_in_path() { /// Search common Node.js version manager directories for a `node` binary and /// return the containing bin directory. -#[cfg(feature = "tauri-runtime")] fn find_node_bin_dir(home: &std::path::Path) -> Option { let mut candidates: Vec = Vec::new(); @@ -184,6 +182,14 @@ fn find_node_bin_dir(home: &std::path::Path) -> Option { } // ── fnm ────────────────────────────────────────────────────────────── + // Prefer active fnm shell path when available. + if let Ok(fnm_multishell_path) = std::env::var("FNM_MULTISHELL_PATH") { + let path = PathBuf::from(fnm_multishell_path); + if path.is_dir() { + candidates.push(path); + } + } + let fnm_dir = std::env::var("FNM_DIR") .map(PathBuf::from) .unwrap_or_else(|_| home.join(".local").join("share").join("fnm")); @@ -195,7 +201,11 @@ fn find_node_bin_dir(home: &std::path::Path) -> Option { entries.sort(); entries.reverse(); for entry in entries { - candidates.push(entry.join("installation").join("bin")); + let installation = entry.join("installation"); + // On Unix fnm places binaries under installation/bin; + // on Windows they sit directly in the installation dir. + let bin = installation.join("bin"); + candidates.push(if bin.is_dir() { bin } else { installation }); } } } @@ -210,7 +220,11 @@ fn find_node_bin_dir(home: &std::path::Path) -> Option { } // Return the first candidate that actually contains a `node` binary. - candidates.into_iter().find(|dir| dir.join("node").is_file()) + // Check both `node` (Unix) and `node.exe` (Windows) so the detection + // works regardless of the current platform. + candidates + .into_iter() + .find(|dir| dir.join("node.exe").is_file() || dir.join("node").is_file()) } /// Prepend a directory to the process `PATH` environment variable.