From be4c65068edbb7bea088bc041aeac8ab3a0612bc Mon Sep 17 00:00:00 2001 From: JongKyung Lee Date: Thu, 6 Aug 2026 22:24:33 +0900 Subject: [PATCH] refactor(env): sort installed versions with node-semver Replace the hand-rolled compare_versions helper in env list with node_semver::Version, which is already a direct dependency of this crate. Unparseable directory names still sort first, and prerelease versions now order correctly per semver. --- crates/vp_global_cli/src/commands/env/list.rs | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/crates/vp_global_cli/src/commands/env/list.rs b/crates/vp_global_cli/src/commands/env/list.rs index 2bd20a2a8b..4ef758e70b 100644 --- a/crates/vp_global_cli/src/commands/env/list.rs +++ b/crates/vp_global_cli/src/commands/env/list.rs @@ -2,7 +2,7 @@ //! //! Handles `vp env list` to show Node.js versions installed in VP_HOME/js_runtime/node/. -use std::{cmp::Ordering, process::ExitStatus}; +use std::process::ExitStatus; use owo_colors::OwoColorize; use serde::Serialize; @@ -38,18 +38,10 @@ pub(super) fn list_installed_versions(node_dir: &std::path::Path) -> Vec }) .collect(); - versions.sort_by(|a, b| compare_versions(a, b)); + versions.sort_by_cached_key(|v| node_semver::Version::parse(v).ok()); versions } -/// Compare two version strings numerically (e.g., "20.18.0" vs "22.13.0"). -fn compare_versions(a: &str, b: &str) -> Ordering { - let parse = |v: &str| -> Vec { v.split('.').filter_map(|p| p.parse().ok()).collect() }; - let a_parts = parse(a); - let b_parts = parse(b); - a_parts.cmp(&b_parts) -} - /// Execute the list command (local installed versions). pub async fn execute(cwd: AbsolutePathBuf, json_output: bool) -> Result { let home_dir = vp_shared::get_vp_home()?; @@ -131,14 +123,6 @@ fn print_human(versions: &[String], current: Option<&str>, default: Option<&str> mod tests { use super::*; - #[test] - fn test_version_cmp() { - assert_eq!(compare_versions("18.20.0", "20.18.0"), Ordering::Less); - assert_eq!(compare_versions("22.13.0", "20.18.0"), Ordering::Greater); - assert_eq!(compare_versions("20.18.0", "20.18.0"), Ordering::Equal); - assert_eq!(compare_versions("20.9.0", "20.18.0"), Ordering::Less); - } - #[test] fn test_list_installed_versions_nonexistent_dir() { let versions = list_installed_versions(std::path::Path::new("/nonexistent/path"));