1
0

build-exe-for-python-sdk.spec.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { spawnSync } from 'node:child_process'
  2. import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
  3. import { tmpdir } from 'node:os'
  4. import { dirname, join, resolve } from 'node:path'
  5. import { afterEach, describe, expect, it } from 'vitest'
  6. const root = resolve(import.meta.dirname, '..')
  7. const script = resolve(root, 'scripts/build-exe-for-python-sdk.ts')
  8. const temporaryDirectories: string[] = []
  9. afterEach(() => {
  10. for (const directory of temporaryDirectories.splice(0)) {
  11. rmSync(directory, { recursive: true, force: true })
  12. }
  13. })
  14. function run(env: NodeJS.ProcessEnv, ...args: string[]) {
  15. return spawnSync(process.execPath, ['--import', 'tsx/esm', script, ...args], {
  16. cwd: root,
  17. encoding: 'utf8',
  18. env: isolatedPnpmEnvironment(env),
  19. })
  20. }
  21. describe('Python runtime executable builder CLI', () => {
  22. it('runs pnpm through its JavaScript entrypoint without a command shell', () => {
  23. const result = run(
  24. { npm_execpath: 'C:\\tools\\pnpm.cjs' },
  25. '--skip-build',
  26. '--dry-run',
  27. '--targets=node24-macos-arm64',
  28. )
  29. expect(result.status).toBe(0)
  30. expect(result.stdout).toContain(`${process.execPath} C:\\tools\\pnpm.cjs run verify-runtime-closure`)
  31. expect(result.stdout).toContain(`${process.execPath} C:\\tools\\pnpm.cjs --filter dsh-python-runtime-closure deploy`)
  32. expect(result.stdout).toContain(`${process.execPath} C:\\tools\\pnpm.cjs exec pkg`)
  33. expect(result.stdout).not.toMatch(/pnpm\.cmd/i)
  34. })
  35. it('resolves the pnpm package behind a Windows command shim', () => {
  36. const setup = mkdtempSync(join(tmpdir(), 'dsh-pnpm-home-'))
  37. temporaryDirectories.push(setup)
  38. const home = join(setup, 'node_modules', '.bin')
  39. const entrypoint = join(setup, 'node_modules', 'pnpm', 'bin', 'pnpm.mjs')
  40. mkdirSync(home, { recursive: true })
  41. mkdirSync(dirname(entrypoint), { recursive: true })
  42. writeFileSync(entrypoint, '')
  43. const result = run(
  44. { npm_execpath: 'C:\\tools\\pnpm.cmd', PNPM_HOME: home },
  45. '--skip-build',
  46. '--dry-run',
  47. '--targets=node24-macos-arm64',
  48. )
  49. expect(result.status).toBe(0)
  50. expect(result.stdout).toContain(`${process.execPath} ${entrypoint} run verify-runtime-closure`)
  51. expect(result.stdout).not.toMatch(/pnpm\.cmd/i)
  52. })
  53. it('accepts the macOS x64 pkg target', () => {
  54. const result = run(
  55. { npm_execpath: 'C:\\tools\\pnpm.cjs' },
  56. '--skip-build',
  57. '--dry-run',
  58. '--targets=node24-macos-x64',
  59. )
  60. expect(result.status).toBe(0)
  61. expect(result.stdout).toContain('exec pkg')
  62. expect(result.stdout).toContain('--sea --targets node24-macos-x64')
  63. })
  64. it('rejects a Windows arm64 product before any build step', () => {
  65. const result = run(
  66. { npm_execpath: 'C:\\tools\\pnpm.cjs' },
  67. '--skip-build',
  68. '--dry-run',
  69. '--targets=node24-win-arm64',
  70. )
  71. expect(result.status).not.toBe(0)
  72. expect(result.stderr).toContain('Windows supports x64 only')
  73. expect(result.stdout).toBe('')
  74. })
  75. })
  76. function isolatedPnpmEnvironment(overrides: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
  77. const environment = Object.fromEntries(
  78. Object.entries(process.env).filter(([key]) => !['npm_execpath', 'pnpm_home'].includes(key.toLowerCase())),
  79. )
  80. return { ...environment, ...overrides }
  81. }