Skip to content

Commit 899e98f

Browse files
committed
refactor(installer): pre-compute Node.js manager decision before menu
Move all user prompts to the menu phase — do_install is now prompt-free. The auto_detect_node_manager() function is pure logic (no I/O) that resolves the Node.js manager default based on: VP_NODE_MANAGER env, existing shims, CI/devcontainer, system node presence. The result is stored in opts.no_node_manager before showing the interactive menu, so the user sees the resolved value ("enabled"/"disabled") and can toggle it in the customize submenu before installation begins. When system node is present and no other signal overrides, the default is "disabled" — the user can enable it via the customize menu. In silent mode (-y), this means shims are not created unless explicitly requested via VP_NODE_MANAGER=yes or auto-detected (CI, no system node).
1 parent 6f502c8 commit 899e98f

1 file changed

Lines changed: 21 additions & 38 deletions

File tree

crates/vite_installer/src/main.rs

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ async fn run(mut opts: cli::Options) -> i32 {
6464
};
6565
let install_dir_display = install_dir.as_path().to_string_lossy().to_string();
6666

67+
// Pre-compute Node.js manager default before showing the menu,
68+
// so the user sees the resolved value and can override it.
69+
if !opts.no_node_manager {
70+
opts.no_node_manager = !auto_detect_node_manager(&install_dir);
71+
}
72+
6773
if !opts.yes {
6874
let proceed = show_interactive_menu(&mut opts, &install_dir_display);
6975
if !proceed {
@@ -193,8 +199,7 @@ async fn do_install(
193199
print_warn(&format!("Shim setup failed (non-fatal): {e}"));
194200
}
195201

196-
let enable_node_manager = should_enable_node_manager(opts, install_dir);
197-
if enable_node_manager {
202+
if !opts.no_node_manager {
198203
if !opts.quiet {
199204
print_info("setting up Node.js version manager...");
200205
}
@@ -217,23 +222,19 @@ async fn do_install(
217222
Ok(())
218223
}
219224

220-
/// Determine whether to enable the Node.js version manager (node/npm/npx shims).
225+
/// Auto-detect whether the Node.js version manager should be enabled.
221226
///
222-
/// Matches the auto-detect logic from install.ps1/install.sh:
223-
/// 1. VP_NODE_MANAGER=yes → enable; VP_NODE_MANAGER=no or --no-node-manager → disable
227+
/// Pure logic — no user prompts. Called once before the interactive menu
228+
/// so the user sees the resolved default and can override it.
229+
///
230+
/// Matches install.ps1/install.sh auto-detect logic:
231+
/// 1. VP_NODE_MANAGER=yes → enable; VP_NODE_MANAGER=no → disable
224232
/// 2. Already managing Node (bin/node.exe exists) → enable (refresh)
225233
/// 3. CI / Codespaces / DevContainer / DevPod → enable
226234
/// 4. No system `node` found → enable
227-
/// 5. Interactive mode with system node → prompt the user
228-
/// 6. Silent mode with system node → disable (don't silently take over)
229-
#[allow(clippy::print_stdout)]
230-
fn should_enable_node_manager(opts: &cli::Options, install_dir: &vite_path::AbsolutePath) -> bool {
231-
// --no-node-manager CLI flag
232-
if opts.no_node_manager {
233-
return false;
234-
}
235-
236-
// VP_NODE_MANAGER env var: "yes" or "no" (both handled here)
235+
/// 5. System node present → disable (user can enable via customize menu)
236+
fn auto_detect_node_manager(install_dir: &vite_path::AbsolutePath) -> bool {
237+
// VP_NODE_MANAGER env var: "yes" or "no"
237238
if let Ok(val) = std::env::var("VP_NODE_MANAGER") {
238239
return val.eq_ignore_ascii_case("yes");
239240
}
@@ -253,27 +254,9 @@ fn should_enable_node_manager(opts: &cli::Options, install_dir: &vite_path::Abso
253254
return true;
254255
}
255256

256-
// Auto-enable if no system node available
257-
if which::which("node").is_err() {
258-
return true;
259-
}
260-
261-
// System node exists — prompt in interactive mode, skip in silent mode
262-
if opts.yes {
263-
return false;
264-
}
265-
266-
println!();
267-
println!(" Would you like Vite+ to manage your Node.js versions?");
268-
println!(
269-
" It adds {}, {}, and {} shims to ~/.vite-plus/bin/ and automatically uses the right version.",
270-
"node".cyan(),
271-
"npm".cyan(),
272-
"npx".cyan()
273-
);
274-
println!(" Opt out anytime with {}.", "vp env off".cyan());
275-
let answer = read_input(" Press Enter to accept (Y/n): ");
276-
answer.is_empty() || answer.eq_ignore_ascii_case("y")
257+
// Auto-enable if no system node available; otherwise default to disabled
258+
// (the interactive menu lets users enable it before proceeding)
259+
which::which("node").is_err()
277260
}
278261

279262
/// Windows locks running `.exe` files — rename the old one out of the way before copying.
@@ -433,7 +416,7 @@ fn show_interactive_menu(opts: &mut cli::Options, install_dir: &str) -> bool {
433416
println!(" Version: {}", version.cyan());
434417
println!(
435418
" Node.js manager: {}",
436-
if opts.no_node_manager { "disabled" } else { "auto-detect" }.cyan()
419+
if opts.no_node_manager { "disabled" } else { "enabled" }.cyan()
437420
);
438421
println!();
439422
println!(" 1) {} (default)", "Proceed with installation".bold());
@@ -466,7 +449,7 @@ fn show_customize_menu(opts: &mut cli::Options) {
466449
println!(" 2) npm registry: [{}]", registry_display.cyan());
467450
println!(
468451
" 3) Node.js manager: [{}]",
469-
if opts.no_node_manager { "disabled" } else { "auto-detect" }.cyan()
452+
if opts.no_node_manager { "disabled" } else { "enabled" }.cyan()
470453
);
471454
println!(
472455
" 4) Modify PATH: [{}]",

0 commit comments

Comments
 (0)