Skip to content

Commit e2a1a36

Browse files
committed
clean up
1 parent 06ed3dd commit e2a1a36

File tree

1 file changed

+33
-110
lines changed

1 file changed

+33
-110
lines changed

crates/vite_global_cli/src/js_executor.rs

Lines changed: 33 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,13 @@ impl JsExecutor {
218218
Ok(self.project_runtime.as_ref().unwrap())
219219
}
220220

221-
/// Check that a resolved runtime's version satisfies vp's engine requirements.
221+
/// Check that a runtime's version satisfies vp's engine requirements.
222222
///
223223
/// Skips silently when:
224224
/// - The runtime is a system install (version == `"system"`)
225225
/// - The version or requirement strings cannot be parsed as semver
226226
///
227-
/// Returns [`Error::NodeVersionIncompatible`] when the version is parseable but
227+
/// Returns [`Error::NodeVersionIncompatible`] when the version is parsable but
228228
/// outside the required range.
229229
async fn check_runtime_compatibility(&self, version: &str) -> Result<(), Error> {
230230
let Some(requirement) = self.get_cli_engines_requirement().await else { return Ok(()) };
@@ -523,120 +523,43 @@ mod tests {
523523
assert_eq!(cmd.as_std().get_program(), OsStr::new(expected_program));
524524
}
525525

526-
// ---- check_runtime_compatibility ----
527-
528-
fn make_runtime_with_version(version: &str) -> JsRuntime {
529-
let binary_path = if cfg!(windows) {
530-
AbsolutePathBuf::new("C:\\node\\node.exe".into()).unwrap()
531-
} else {
532-
AbsolutePathBuf::new("/usr/local/bin/node".into()).unwrap()
533-
};
534-
let mut runtime = JsRuntime::from_system(JsRuntimeType::Node, binary_path);
535-
runtime.version = version.into();
536-
runtime
537-
}
538-
539-
#[test]
540-
fn compatible_version_passes() {
541-
let runtime = make_runtime_with_version("22.12.0");
542-
assert!(
543-
check_runtime_compatibility(&runtime, "^20.19.0 || >=22.12.0").is_ok(),
544-
"22.12.0 should satisfy ^20.19.0 || >=22.12.0"
545-
);
546-
}
547-
548-
#[test]
549-
fn compatible_version_with_v_prefix_passes() {
550-
let runtime = make_runtime_with_version("v20.19.0");
551-
assert!(
552-
check_runtime_compatibility(&runtime, "^20.19.0 || >=22.12.0").is_ok(),
553-
"v20.19.0 should satisfy ^20.19.0 || >=22.12.0"
554-
);
555-
}
556-
557-
#[test]
558-
fn incompatible_version_returns_error() {
559-
let runtime = make_runtime_with_version("18.0.0");
560-
let err = check_runtime_compatibility(&runtime, "^20.19.0 || >=22.12.0")
561-
.expect_err("18.0.0 should not satisfy ^20.19.0 || >=22.12.0");
562-
assert!(
563-
matches!(err, Error::NodeVersionIncompatible { .. }),
564-
"expected NodeVersionIncompatible, got {err:?}"
565-
);
566-
}
567-
568-
#[test]
569-
fn system_runtime_skips_check() {
570-
// from_system() sets version == "system"
571-
let binary_path = if cfg!(windows) {
572-
AbsolutePathBuf::new("C:\\node\\node.exe".into()).unwrap()
573-
} else {
574-
AbsolutePathBuf::new("/usr/local/bin/node".into()).unwrap()
575-
};
576-
let runtime = JsRuntime::from_system(JsRuntimeType::Node, binary_path);
577-
assert_eq!(runtime.version(), "system");
578-
assert!(
579-
check_runtime_compatibility(&runtime, "^20.19.0 || >=22.12.0").is_ok(),
580-
"system runtime should pass the check unconditionally"
581-
);
582-
}
583-
584-
#[test]
585-
fn unparsable_version_skips_check() {
586-
let runtime = make_runtime_with_version("not-a-version");
587-
assert!(
588-
check_runtime_compatibility(&runtime, "^20.19.0 || >=22.12.0").is_ok(),
589-
"unparsable version should not cause an error"
590-
);
591-
}
592-
593-
#[test]
594-
fn invalid_requirement_skips_check() {
595-
let runtime = make_runtime_with_version("18.0.0");
596-
assert!(
597-
check_runtime_compatibility(&runtime, "not-a-range").is_ok(),
598-
"invalid requirement range should not cause an error"
599-
);
600-
}
601-
602-
// ---- get_cli_engines_requirement ----
603-
526+
/// Pin Node.js to 20.0.0
527+
/// and any vp command should be blocked with a clear error instead of crashing
604528
#[tokio::test]
605-
async fn get_cli_engines_requirement_reads_from_package_json() {
606-
use std::io::Write;
607-
529+
async fn incompatible_node_version_should_be_blocked() {
608530
use tempfile::TempDir;
609-
531+
use vite_shared::EnvConfig;
532+
533+
// Point scripts_dir at the real packages/cli/dist so that
534+
// get_cli_engines_requirement() reads the actual engines.node from
535+
// packages/cli/package.json. The dist/ directory need not exist — only
536+
// its parent (packages/cli/) and the package.json within it are read.
537+
let scripts_dir = AbsolutePathBuf::new(
538+
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../packages/cli/dist"),
539+
)
540+
.unwrap();
541+
542+
// Use any existing directory as project_path; the session override
543+
// fires before any project-source lookup or network download.
610544
let temp_dir = TempDir::new().unwrap();
611-
// The scripts dir is `<pkg_dir>/dist`, and get_cli_package_dir returns its parent.
612-
let dist_dir = temp_dir.path().join("dist");
613-
std::fs::create_dir(&dist_dir).unwrap();
614-
615-
let pkg_json_content = r#"{ "engines": { "node": "^20.19.0 || >=22.12.0" } }"#;
616-
let mut f = std::fs::File::create(temp_dir.path().join("package.json")).unwrap();
617-
f.write_all(pkg_json_content.as_bytes()).unwrap();
618-
619-
let scripts_dir = AbsolutePathBuf::new(dist_dir).unwrap();
620-
let executor = JsExecutor::new(Some(scripts_dir));
545+
let project_path = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
621546

622-
let req = executor.get_cli_engines_requirement().await;
623-
assert_eq!(req.as_deref(), Some("^20.19.0 || >=22.12.0"));
624-
}
625-
626-
#[tokio::test]
627-
async fn get_cli_engines_requirement_returns_none_when_missing() {
628-
use tempfile::TempDir;
629-
630-
let temp_dir = TempDir::new().unwrap();
631-
let dist_dir = temp_dir.path().join("dist");
632-
std::fs::create_dir(&dist_dir).unwrap();
547+
// Simulate `.node-version: 20.0.0` / `vp env use 20.0.0` via a session override.
548+
let _guard = EnvConfig::test_guard(EnvConfig {
549+
node_version: Some("20.0.0".to_string()),
550+
..EnvConfig::for_test()
551+
});
633552

634-
// No package.json → should return None
635-
let scripts_dir = AbsolutePathBuf::new(dist_dir).unwrap();
636-
let executor = JsExecutor::new(Some(scripts_dir));
553+
let mut executor = JsExecutor::new(Some(scripts_dir));
554+
let err = executor
555+
.ensure_project_runtime(&project_path)
556+
.await
557+
.expect_err("Node.js 20.0.0 should be rejected as incompatible with vp requirements");
637558

638-
let req = executor.get_cli_engines_requirement().await;
639-
assert!(req.is_none());
559+
assert!(
560+
matches!(&err, Error::NodeVersionIncompatible { version, .. } if version == "20.0.0"),
561+
"expected NodeVersionIncompatible for 20.0.0, got: {err:?}"
562+
);
640563
}
641564

642565
#[tokio::test]

0 commit comments

Comments
 (0)