e2e-windows-spawn.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * Manual end-to-end check for the Windows crossSpawn fix.
  3. *
  4. * Reproduces the auto-updater failure: `bun` on PATH only as npm `.cmd`
  5. * shims (no real bun.exe in any PATH directory). Temporarily hides any
  6. * bun.exe in the npm shim directory, then runs crossSpawn(['bun', ...]).
  7. *
  8. * Run with: bun scripts/e2e-windows-spawn.ts
  9. * Expected on Windows: exit 0 and a printed bun version.
  10. * Before the fix: spawn error ENOENT for 'bun'.
  11. */
  12. import { renameSync } from 'node:fs';
  13. import { join } from 'node:path';
  14. import { crossSpawn } from '../src/utils/compat';
  15. function main(): void {
  16. if (process.platform !== 'win32') {
  17. console.log('skip: not win32');
  18. return;
  19. }
  20. const shimDir = join(process.env.APPDATA ?? '', 'npm');
  21. const realExe = join(shimDir, 'bun.exe');
  22. const hidden = `${realExe}.e2e-hidden`;
  23. let restored = false;
  24. const restore = (): void => {
  25. if (restored) return;
  26. try {
  27. renameSync(hidden, realExe);
  28. } catch {
  29. /* nothing to restore */
  30. }
  31. restored = true;
  32. };
  33. try {
  34. renameSync(realExe, hidden);
  35. console.log('hid bun.exe; PATH now exposes bun.cmd shims only');
  36. } catch {
  37. console.log('no bun.exe in shim dir; nothing to hide');
  38. }
  39. const proc = crossSpawn(['bun', '--version'], {
  40. stdout: 'pipe',
  41. stderr: 'pipe',
  42. });
  43. proc.exited
  44. .then(async (code) => {
  45. if (code === 0) {
  46. console.log(
  47. `bun resolved via shim, version=${(await proc.stdout()).trim()}`,
  48. );
  49. } else {
  50. console.log(
  51. `bun exited ${code}: ${(await proc.stderr()).trim().slice(0, 200)}`,
  52. );
  53. }
  54. restore();
  55. process.exit(code === 0 ? 0 : 1);
  56. })
  57. .catch((err: Error) => {
  58. console.log(`spawn failed: ${err.message}`);
  59. restore();
  60. process.exit(1);
  61. });
  62. }
  63. main();