Files
dsh-web/market/shell/scripts/build-container-python.mjs

46 lines
1.6 KiB
JavaScript

/**
* Bundle Python's front end as a single Node program for the container to run.
*
* The interpreter itself is fetched at first use — it is 14 MB of WebAssembly
* and does not belong in a page's JavaScript — but everything that decides what
* `python` and `pip` *mean* is built here and written into the container at
* boot, next to the shell. Same reason as the shell: a program that arrived
* over the network could fail to arrive, and then the machine would have a
* Python that cannot be called.
*/
import { build } from 'esbuild'
import { mkdirSync, writeFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const result = await build({
entryPoints: [resolve(root, 'src/python/container-python.ts')],
bundle: true,
platform: 'node',
target: 'node22',
format: 'cjs',
minify: true,
legalComments: 'none',
write: false,
})
const [output] = result.outputFiles
const generated = resolve(root, 'src/generated')
mkdirSync(generated, { recursive: true })
writeFileSync(resolve(generated, 'container-python.ts'), [
'/**',
' * The `python` and `pip` program the container runs, as source text.',
' *',
' * Generated by `scripts/build-container-python.mjs`; do not edit. The app',
' * writes this into the container at boot so the machine has a real Python.',
' */',
'',
`export const CONTAINER_PYTHON = ${JSON.stringify(output.text)}`,
'',
].join('\n'))
console.log(`container python: ${String(Math.round(output.text.length / 1024))} kB`)