fix(python-runtime): fall back to node-pty prebuild
This commit is contained in:
49
scripts/build-exe-for-python-sdk-native-pty.spec.ts
Normal file
49
scripts/build-exe-for-python-sdk-native-pty.spec.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||||
|
import { tmpdir } from 'node:os'
|
||||||
|
import { dirname, join } from 'node:path'
|
||||||
|
import { afterEach, describe, expect, it } from 'vitest'
|
||||||
|
import { resolveLinuxNodePtyAddon } from './build-exe-for-python-sdk-native-pty.ts'
|
||||||
|
|
||||||
|
const roots: string[] = []
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('resolveLinuxNodePtyAddon', () => {
|
||||||
|
it('prefers the manylinux build produced by the release workflow', () => {
|
||||||
|
const root = temporaryPackage()
|
||||||
|
const built = createAddon(root, 'build', 'Release', 'pty.node')
|
||||||
|
createAddon(root, 'prebuilds', 'linux-x64', 'pty.node')
|
||||||
|
|
||||||
|
expect(resolveLinuxNodePtyAddon(root, 'x64')).toBe(built)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('uses the target prebuild after an ordinary beta install', () => {
|
||||||
|
const root = temporaryPackage()
|
||||||
|
const prebuilt = createAddon(root, 'prebuilds', 'linux-arm64', 'pty.node')
|
||||||
|
|
||||||
|
expect(resolveLinuxNodePtyAddon(root, 'arm64')).toBe(prebuilt)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('reports both expected locations when no addon is installed', () => {
|
||||||
|
const root = temporaryPackage()
|
||||||
|
|
||||||
|
expect(() => resolveLinuxNodePtyAddon(root, 'x64')).toThrow(
|
||||||
|
`node-pty addon is absent from both ${join(root, 'build', 'Release', 'pty.node')} and ${join(root, 'prebuilds', 'linux-x64', 'pty.node')}`,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function temporaryPackage(): string {
|
||||||
|
const root = mkdtempSync(join(tmpdir(), 'dsh-node-pty-addon-'))
|
||||||
|
roots.push(root)
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAddon(root: string, ...segments: string[]): string {
|
||||||
|
const path = join(root, ...segments)
|
||||||
|
mkdirSync(dirname(path), { recursive: true })
|
||||||
|
writeFileSync(path, '')
|
||||||
|
return path
|
||||||
|
}
|
||||||
23
scripts/build-exe-for-python-sdk-native-pty.ts
Normal file
23
scripts/build-exe-for-python-sdk-native-pty.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/** Resolve the native node-pty input used by the Python SDK runtime builder. */
|
||||||
|
|
||||||
|
import { existsSync } from 'node:fs'
|
||||||
|
import { join } from 'node:path'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefer the workflow's manylinux build and fall back to node-pty's target prebuild.
|
||||||
|
* @param packageDirectory - installed node-pty package directory.
|
||||||
|
* @param arch - Linux target architecture.
|
||||||
|
* @returns the existing addon path.
|
||||||
|
*/
|
||||||
|
export function resolveLinuxNodePtyAddon(
|
||||||
|
packageDirectory: string,
|
||||||
|
arch: 'x64' | 'arm64',
|
||||||
|
): string {
|
||||||
|
const built = join(packageDirectory, 'build', 'Release', 'pty.node')
|
||||||
|
if (existsSync(built)) return built
|
||||||
|
const prebuilt = join(packageDirectory, 'prebuilds', `linux-${arch}`, 'pty.node')
|
||||||
|
if (existsSync(prebuilt)) return prebuilt
|
||||||
|
throw new Error(
|
||||||
|
`build-exe-for-python-sdk: node-pty addon is absent from both ${built} and ${prebuilt}.`,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import { existsSync, statSync } from 'node:fs'
|
|||||||
import { chmod, copyFile, cp, lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from 'node:fs/promises'
|
import { chmod, copyFile, cp, lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from 'node:fs/promises'
|
||||||
import { basename, dirname, join, resolve, sep } from 'node:path'
|
import { basename, dirname, join, resolve, sep } from 'node:path'
|
||||||
import { parseArgs } from 'node:util'
|
import { parseArgs } from 'node:util'
|
||||||
|
import { resolveLinuxNodePtyAddon } from './build-exe-for-python-sdk-native-pty.ts'
|
||||||
|
|
||||||
const root = resolve(import.meta.dirname, '..')
|
const root = resolve(import.meta.dirname, '..')
|
||||||
|
|
||||||
@@ -409,8 +410,8 @@ class SingleExeBuild {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put the target node-pty addon in the staged closure. Linux npm installs
|
* Put the target node-pty addon in the staged closure. The release workflow
|
||||||
* build it from source, but legacy deploy omits that side-effect directory.
|
* provides a manylinux build; ordinary installs use node-pty's target prebuild.
|
||||||
* @param target - the pkg target whose native addon is being staged.
|
* @param target - the pkg target whose native addon is being staged.
|
||||||
*/
|
*/
|
||||||
private async prepareNativePty(target: Target): Promise<void> {
|
private async prepareNativePty(target: Target): Promise<void> {
|
||||||
@@ -418,8 +419,16 @@ class SingleExeBuild {
|
|||||||
if (this.cli.dryRun) console.log(`build-exe-for-python-sdk: [dry-run] rm -rf ${stagedBuild}`)
|
if (this.cli.dryRun) console.log(`build-exe-for-python-sdk: [dry-run] rm -rf ${stagedBuild}`)
|
||||||
else await rm(stagedBuild, { recursive: true, force: true })
|
else await rm(stagedBuild, { recursive: true, force: true })
|
||||||
if (target.platform !== 'linux') return
|
if (target.platform !== 'linux') return
|
||||||
const source = join(root, 'packages', 'subprocess', 'subprocess-local', 'node_modules', 'node-pty', 'build', 'Release', 'pty.node')
|
const packageDirectory = join(
|
||||||
|
root,
|
||||||
|
'packages',
|
||||||
|
'subprocess',
|
||||||
|
'subprocess-local',
|
||||||
|
'node_modules',
|
||||||
|
'node-pty',
|
||||||
|
)
|
||||||
const destination = join(stagedBuild, 'Release', 'pty.node')
|
const destination = join(stagedBuild, 'Release', 'pty.node')
|
||||||
|
const source = resolveLinuxNodePtyAddon(packageDirectory, target.arch)
|
||||||
if (this.cli.dryRun) {
|
if (this.cli.dryRun) {
|
||||||
console.log(`build-exe-for-python-sdk: [dry-run] cp ${source} ${destination}`)
|
console.log(`build-exe-for-python-sdk: [dry-run] cp ${source} ${destination}`)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user