@@ -230,6 +230,13 @@ pub async fn resolve_version(cwd: &AbsolutePath) -> Result<VersionResolution, Er
230230 } ) ;
231231 }
232232
233+ resolve_version_from_files ( cwd) . await
234+ }
235+
236+ /// Resolve Node.js version from project files only (skipping session overrides).
237+ ///
238+ /// This is used by `vp env use` without arguments to revert to file-based resolution.
239+ pub async fn resolve_version_from_files ( cwd : & AbsolutePath ) -> Result < VersionResolution , Error > {
233240 let provider = NodeProvider :: new ( ) ;
234241
235242 // Use shared version resolution with directory walking
@@ -1091,4 +1098,76 @@ mod tests {
10911098 assert_eq ! ( resolution. version, "20.18.0" ) ;
10921099 assert_eq ! ( resolution. source, ".node-version" ) ;
10931100 }
1101+
1102+ // ── resolve_version_from_files tests ──
1103+
1104+ /// Verify that `resolve_version_from_files` ignores session env var override.
1105+ /// This is the key behavior for `vp env use` without arguments.
1106+ #[ tokio:: test]
1107+ async fn test_resolve_version_from_files_ignores_env_var ( ) {
1108+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
1109+ let temp_path = AbsolutePathBuf :: new ( temp_dir. path ( ) . to_path_buf ( ) ) . unwrap ( ) ;
1110+ let _guard = vite_shared:: EnvConfig :: test_guard ( vite_shared:: EnvConfig {
1111+ node_version : Some ( "22.0.0" . into ( ) ) ,
1112+ ..vite_shared:: EnvConfig :: for_test ( )
1113+ } ) ;
1114+
1115+ // Create .node-version file with different version
1116+ tokio:: fs:: write ( temp_path. join ( ".node-version" ) , "20.18.0\n " ) . await . unwrap ( ) ;
1117+
1118+ // resolve_version_from_files should skip env var and use .node-version
1119+ let resolution = resolve_version_from_files ( & temp_path) . await . unwrap ( ) ;
1120+
1121+ assert_eq ! ( resolution. version, "20.18.0" ) ;
1122+ assert_eq ! ( resolution. source, ".node-version" ) ;
1123+ }
1124+
1125+ /// Verify that `resolve_version_from_files` ignores session file override.
1126+ #[ tokio:: test]
1127+ async fn test_resolve_version_from_files_ignores_session_file ( ) {
1128+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
1129+ let temp_path = AbsolutePathBuf :: new ( temp_dir. path ( ) . to_path_buf ( ) ) . unwrap ( ) ;
1130+ let _guard = vite_shared:: EnvConfig :: test_guard (
1131+ vite_shared:: EnvConfig :: for_test_with_home ( temp_dir. path ( ) ) ,
1132+ ) ;
1133+
1134+ // Write session version file
1135+ write_session_version ( "22.0.0" ) . await . unwrap ( ) ;
1136+
1137+ // Create .node-version file with different version
1138+ tokio:: fs:: write ( temp_path. join ( ".node-version" ) , "20.18.0\n " ) . await . unwrap ( ) ;
1139+
1140+ // resolve_version_from_files should skip session file and use .node-version
1141+ let resolution = resolve_version_from_files ( & temp_path) . await . unwrap ( ) ;
1142+
1143+ assert_eq ! ( resolution. version, "20.18.0" ) ;
1144+ assert_eq ! ( resolution. source, ".node-version" ) ;
1145+
1146+ // Clean up
1147+ delete_session_version ( ) . await . unwrap ( ) ;
1148+ }
1149+
1150+ /// Verify that `resolve_version_from_files` still respects both env var and session file.
1151+ #[ tokio:: test]
1152+ async fn test_resolve_version_still_respects_overrides ( ) {
1153+ let temp_dir = TempDir :: new ( ) . unwrap ( ) ;
1154+ let temp_path = AbsolutePathBuf :: new ( temp_dir. path ( ) . to_path_buf ( ) ) . unwrap ( ) ;
1155+ let _guard = vite_shared:: EnvConfig :: test_guard ( vite_shared:: EnvConfig {
1156+ node_version : Some ( "22.0.0" . into ( ) ) ,
1157+ ..vite_shared:: EnvConfig :: for_test_with_home ( temp_dir. path ( ) )
1158+ } ) ;
1159+
1160+ // Create .node-version file
1161+ tokio:: fs:: write ( temp_path. join ( ".node-version" ) , "20.18.0\n " ) . await . unwrap ( ) ;
1162+
1163+ // resolve_version should still use env var (existing behavior)
1164+ let resolution = resolve_version ( & temp_path) . await . unwrap ( ) ;
1165+ assert_eq ! ( resolution. version, "22.0.0" ) ;
1166+ assert_eq ! ( resolution. source, VERSION_ENV_VAR ) ;
1167+
1168+ // But resolve_version_from_files should skip it
1169+ let resolution_from_files = resolve_version_from_files ( & temp_path) . await . unwrap ( ) ;
1170+ assert_eq ! ( resolution_from_files. version, "20.18.0" ) ;
1171+ assert_eq ! ( resolution_from_files. source, ".node-version" ) ;
1172+ }
10941173}
0 commit comments