Files
deepseek-harness/scripts/executable-packaging.ts
T

114 lines
4.7 KiB
TypeScript

/** Shared production-deploy preparation for the SDK and SSH executable carriers. */
import { existsSync } from 'node:fs'
import { cp, lstat, mkdir, readFile, readdir, realpath, rm, unlink } from 'node:fs/promises'
import { dirname, extname, join, resolve, sep } from 'node:path'
/**
* Resolve pnpm without invoking a command shell, including Windows shims.
* @param args - pnpm arguments.
* @returns the executable and its argument vector.
*/
export function pnpmInvocation(args: string[]): [command: string, args: string[]] {
const entrypoint = process.env.npm_execpath?.trim()
if (entrypoint !== undefined && entrypoint !== '') {
const extension = extname(entrypoint).toLowerCase()
if (extension === '.js' || extension === '.cjs' || extension === '.mjs') {
return [process.execPath, [entrypoint, ...args]]
}
if (extension !== '.cmd') return [entrypoint, args]
}
const home = process.env.PNPM_HOME?.trim()
if (home !== undefined && home !== '') {
const packageBin = resolve(home, '..', 'pnpm', 'bin')
for (const filename of ['pnpm.mjs', 'pnpm.cjs']) {
const candidate = resolve(packageBin, filename)
if (existsSync(candidate)) return [process.execPath, [candidate, ...args]]
}
}
if (process.platform === 'win32') {
throw new Error('executable-packaging: pnpm must expose a JavaScript entrypoint through npm_execpath or PNPM_HOME on Windows.')
}
return ['pnpm', args]
}
/**
* Restore direct dependencies omitted by pnpm's legacy hoister, excluding nested module trees.
* @param staging - deployed runtime root.
* @param sourceNodeModules - deploy source's installed dependencies.
* @returns names restored from the source installation.
*/
export async function restoreLegacyHoists(staging: string, sourceNodeModules: string): Promise<string[]> {
const manifestPath = join(staging, 'package.json')
const manifest = JSON.parse(await readFile(manifestPath, 'utf8')) as {
dependencies?: Record<string, string>
}
const restored: string[] = []
for (const dependency of Object.keys(manifest.dependencies ?? {}).sort()) {
const destination = join(staging, 'node_modules', dependency)
if (existsSync(destination)) continue
const source = join(sourceNodeModules, dependency)
if (!existsSync(source)) {
throw new Error(
`executable-packaging: deployed dependency ${dependency} is absent from both ${destination} and ${source}.`,
)
}
await mkdir(dirname(destination), { recursive: true })
const nestedNodeModules = join(source, 'node_modules')
await cp(source, destination, {
recursive: true,
dereference: true,
filter: path => path !== nestedNodeModules && !path.startsWith(nestedNodeModules + sep),
})
restored.push(dependency)
}
const stillMissing = Object.keys(manifest.dependencies ?? {})
.filter(dependency => !existsSync(join(staging, 'node_modules', dependency)))
if (stillMissing.length > 0) {
throw new Error(`executable-packaging: staged dependencies remain missing: ${stillMissing.join(', ')}.`)
}
return restored
}
/**
* Materialize deployed package links and remove command shims before embedding files.
* @param nodeModules - deployed dependency directory, owned by the current build.
*/
export async function materializeStagedLinks(nodeModules: string): Promise<void> {
let remaining = await findSymlink(nodeModules)
while (remaining !== undefined) {
const segments = remaining.slice(nodeModules.length + 1).split(sep)
const binIndex = segments.lastIndexOf('.bin')
if (binIndex >= 0) {
const directory = join(nodeModules, ...segments.slice(0, binIndex + 1))
if ((await lstat(directory)).isSymbolicLink()) await unlink(directory)
else await rm(directory, { recursive: true, force: true })
remaining = await findSymlink(nodeModules)
continue
}
const destination = remaining
const source = await realpath(destination)
const nestedNodeModules = join(source, 'node_modules')
await unlink(destination)
await cp(source, destination, {
recursive: true,
dereference: true,
filter: path => path !== nestedNodeModules && !path.startsWith(nestedNodeModules + sep),
})
remaining = await findSymlink(nodeModules)
}
}
/** Return the first symbolic link below a directory, if one exists. */
async function findSymlink(directory: string): Promise<string | undefined> {
for (const entry of await readdir(directory, { withFileTypes: true })) {
const path = join(directory, entry.name)
const metadata = await lstat(path)
if (metadata.isSymbolicLink()) return path
if (metadata.isDirectory()) {
const nested = await findSymlink(path)
if (nested !== undefined) return nested
}
}
return undefined
}