Skip to content

Commit 1eb39c6

Browse files
fix(cli): make vpx run .cmd instead of Unix binary on Windows (#1652)
Fix #1651 --------- Co-authored-by: MK (fengmk2) <fengmk2@gmail.com>
1 parent d5e8e61 commit 1eb39c6

1 file changed

Lines changed: 63 additions & 9 deletions

File tree

  • crates/vite_global_cli/src/commands

crates/vite_global_cli/src/commands/vpx.rs

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,15 @@ pub fn find_local_binary(cwd: &AbsolutePath, cmd: &str) -> Option<AbsolutePathBu
243243
let mut current = cwd;
244244
loop {
245245
let bin_dir = current.join("node_modules").join(".bin");
246-
let bin_path = bin_dir.join(cmd);
247246

248-
if bin_path.as_path().exists() {
249-
return Some(bin_path);
247+
#[cfg(not(windows))]
248+
{
249+
let bin_path = bin_dir.join(cmd);
250+
if bin_path.as_path().exists() {
251+
return Some(bin_path);
252+
}
250253
}
251254

252-
// On Windows, check for .cmd extension
253255
#[cfg(windows)]
254256
{
255257
let cmd_path = bin_dir.join(format!("{cmd}.cmd"));
@@ -536,11 +538,18 @@ mod tests {
536538
let temp_dir = tempfile::tempdir().unwrap();
537539
let temp_path = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
538540

539-
// Create node_modules/.bin/eslint
541+
// Create node_modules/.bin/eslint and eslint.cmd
540542
let bin_dir = temp_path.join("node_modules").join(".bin");
541543
std::fs::create_dir_all(&bin_dir).unwrap();
544+
// Unix script
545+
std::fs::write(bin_dir.join("eslint"), "#!/bin/sh\n").unwrap();
546+
#[cfg(windows)]
547+
std::fs::write(bin_dir.join("eslint.cmd"), "@eslint %*\r\n").unwrap();
548+
549+
#[cfg(not(windows))]
542550
let eslint_path = bin_dir.join("eslint");
543-
std::fs::write(&eslint_path, "#!/bin/sh\n").unwrap();
551+
#[cfg(windows)]
552+
let eslint_path = bin_dir.join("eslint.cmd");
544553

545554
let result = find_local_binary(&temp_path, "eslint");
546555
assert!(result.is_some());
@@ -552,11 +561,17 @@ mod tests {
552561
let temp_dir = tempfile::tempdir().unwrap();
553562
let temp_path = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
554563

555-
// Create node_modules/.bin/eslint at root
564+
// Create node_modules/.bin/eslint and eslint.cmd at root
556565
let bin_dir = temp_path.join("node_modules").join(".bin");
557566
std::fs::create_dir_all(&bin_dir).unwrap();
567+
std::fs::write(bin_dir.join("eslint"), "#!/bin/sh\n").unwrap();
568+
#[cfg(windows)]
569+
std::fs::write(bin_dir.join("eslint.cmd"), "@eslint %*\r\n").unwrap();
570+
571+
#[cfg(not(windows))]
558572
let eslint_path = bin_dir.join("eslint");
559-
std::fs::write(&eslint_path, "#!/bin/sh\n").unwrap();
573+
#[cfg(windows)]
574+
let eslint_path = bin_dir.join("eslint.cmd");
560575

561576
// Create nested directory
562577
let nested_dir = temp_path.join("packages").join("app");
@@ -586,19 +601,58 @@ mod tests {
586601
let root_bin = temp_path.join("node_modules").join(".bin");
587602
std::fs::create_dir_all(&root_bin).unwrap();
588603
std::fs::write(root_bin.join("eslint"), "root").unwrap();
604+
#[cfg(windows)]
605+
std::fs::write(root_bin.join("eslint.cmd"), "@eslint %*\r\n").unwrap();
589606

590607
// Create eslint in nested package
591608
let nested = temp_path.join("packages").join("app");
592609
let nested_bin = nested.join("node_modules").join(".bin");
593610
std::fs::create_dir_all(&nested_bin).unwrap();
594611
std::fs::write(nested_bin.join("eslint"), "nested").unwrap();
612+
#[cfg(windows)]
613+
std::fs::write(nested_bin.join("eslint.cmd"), "@eslint %*\r\n").unwrap();
614+
615+
#[cfg(not(windows))]
616+
let nested_bin = nested_bin.join("eslint");
617+
#[cfg(windows)]
618+
let nested_bin = nested_bin.join("eslint.cmd");
595619

596620
let nested_abs = AbsolutePathBuf::new(nested.as_path().to_path_buf()).unwrap();
597621
let result = find_local_binary(&nested_abs, "eslint");
598622
assert!(result.is_some());
599623
// Should find the nested one first
600624
let found = result.unwrap();
601-
assert_eq!(found.as_path(), nested_bin.join("eslint").as_path());
625+
assert_eq!(found.as_path(), nested_bin.as_path());
626+
}
627+
628+
#[cfg(windows)]
629+
#[test]
630+
fn test_find_local_binary_windows_prefers_cmd_over_extensionless() {
631+
let temp_dir = tempfile::tempdir().unwrap();
632+
let temp_path = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
633+
634+
let bin_dir = temp_path.join("node_modules").join(".bin");
635+
std::fs::create_dir_all(&bin_dir).unwrap();
636+
std::fs::write(bin_dir.join("playwright"), "#!/bin/sh\n").unwrap();
637+
std::fs::write(bin_dir.join("playwright.cmd"), "@playwright %*\r\n").unwrap();
638+
639+
let result = find_local_binary(&temp_path, "playwright");
640+
assert!(result.is_some());
641+
assert_eq!(result.unwrap().as_path(), bin_dir.join("playwright.cmd").as_path());
642+
}
643+
644+
#[cfg(windows)]
645+
#[test]
646+
fn test_find_local_binary_windows_ignores_extensionless_only() {
647+
let temp_dir = tempfile::tempdir().unwrap();
648+
let temp_path = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
649+
650+
let bin_dir = temp_path.join("node_modules").join(".bin");
651+
std::fs::create_dir_all(&bin_dir).unwrap();
652+
std::fs::write(bin_dir.join("playwright"), "#!/bin/sh\n").unwrap();
653+
654+
let result = find_local_binary(&temp_path, "playwright");
655+
assert!(result.is_none());
602656
}
603657

604658
// =========================================================================

0 commit comments

Comments
 (0)