Delegate build logic to external script, simplify build target representation

This commit is contained in:
Chris Wanstrath 2026-02-19 19:16:12 -08:00
parent 18cf4243fa
commit aaf4660816

View File

@ -59,46 +59,33 @@ app.all('/api/tools/:tool/:path{.+}', async c => {
}) })
}) })
const CLI_ENTRY = import.meta.dir + '/../cli/index.ts' const BUILD_SCRIPT = import.meta.dir + '/../../scripts/build.ts'
const DIST_DIR = import.meta.dir + '/../../dist' const DIST_DIR = import.meta.dir + '/../../dist'
const INSTALL_SCRIPT = await Bun.file(import.meta.dir + '/install.sh').text() const INSTALL_SCRIPT = await Bun.file(import.meta.dir + '/install.sh').text()
interface BuildTarget { const BUILD_TARGETS = [
arch: string 'toes-macos-arm64',
name: string 'toes-macos-x64',
os: string 'toes-linux-arm64',
} 'toes-linux-x64',
const BUILD_TARGETS: BuildTarget[] = [
{ os: 'darwin', arch: 'arm64', name: 'toes-macos-arm64' },
{ os: 'darwin', arch: 'x64', name: 'toes-macos-x64' },
{ os: 'linux', arch: 'arm64', name: 'toes-linux-arm64' },
{ os: 'linux', arch: 'x64', name: 'toes-linux-x64' },
] ]
const buildInFlight = new Map<string, Promise<boolean>>() const buildInFlight = new Map<string, Promise<boolean>>()
async function buildBinary(target: BuildTarget): Promise<boolean> { async function buildBinary(name: string): Promise<boolean> {
const existing = buildInFlight.get(target.name) const existing = buildInFlight.get(name)
if (existing) return existing if (existing) return existing
const promise = (async () => { const promise = (async () => {
const { existsSync, mkdirSync } = await import('fs') const proc = Bun.spawn(
if (!existsSync(DIST_DIR)) mkdirSync(DIST_DIR, { recursive: true }) ['bun', 'run', BUILD_SCRIPT, `--target=${name}`],
{ stdout: 'inherit', stderr: 'inherit' },
const proc = Bun.spawn([ )
'bun', 'build', CLI_ENTRY, '--compile', return (await proc.exited) === 0
'--target', `bun-${target.os}-${target.arch}`,
'--minify', '--sourcemap=external',
'--outfile', `${DIST_DIR}/${target.name}`,
], { stdout: 'inherit', stderr: 'inherit' })
const exitCode = await proc.exited
return exitCode === 0
})() })()
buildInFlight.set(target.name, promise) buildInFlight.set(name, promise)
promise.finally(() => buildInFlight.delete(target.name)) promise.finally(() => buildInFlight.delete(name))
return promise return promise
} }
@ -117,9 +104,8 @@ app.get('/dist/:file', async c => {
} }
const bunFile = Bun.file(`${DIST_DIR}/${file}`) const bunFile = Bun.file(`${DIST_DIR}/${file}`)
if (!(await bunFile.exists())) { if (!(await bunFile.exists())) {
const target = BUILD_TARGETS.find(t => t.name === file) if (!BUILD_TARGETS.includes(file)) return c.text('Not found', 404)
if (!target) return c.text('Not found', 404) const ok = await buildBinary(file)
const ok = await buildBinary(target)
if (!ok) return c.text(`Failed to build "${file}"`, 500) if (!ok) return c.text(`Failed to build "${file}"`, 500)
} }
return new Response(Bun.file(`${DIST_DIR}/${file}`), { return new Response(Bun.file(`${DIST_DIR}/${file}`), {