#!/usr/bin/env node import { spawn, spawnSync } from 'child_process' import { fileURLToPath } from 'url' import { dirname, join } from 'path' import { existsSync } from 'fs' import { platform, arch } from 'os' const here = dirname(fileURLToPath(import.meta.url)) const exeSuffix = platform() === 'win32' ? '.exe' : '' const codegenDir = join(here, '..', '..', 'mizan-codegen') const manifest = join(codegenDir, 'Cargo.toml') function resolveBinary() { if (existsSync(manifest)) { // Rebuilding unconditionally is what keeps the binary in step with the // crate; an up-to-date cargo build is a no-op, a stale target/release // artifact is otherwise indistinguishable from a fresh one. const build = spawnSync( 'cargo', ['build', '--release', '--quiet', '--manifest-path', manifest], { stdio: 'inherit' }, ) if (build.error) { console.error(`[mizan-generate] cannot run cargo: ${build.error.message}`) console.error(`[mizan-generate] cargo builds ${manifest}; install a Rust toolchain`) process.exit(1) } if (build.status !== 0) { console.error(`[mizan-generate] cargo build --release failed for ${manifest}`) process.exit(build.status) } return join(codegenDir, 'target', 'release', `mizan-generate${exeSuffix}`) } const packaged = join(here, `mizan-generate-${platform()}-${arch()}${exeSuffix}`) if (!existsSync(packaged)) { console.error(`[mizan-generate] no binary packaged for ${platform()}-${arch()}: ${packaged}`) process.exit(1) } return packaged } const binPath = resolveBinary() const child = spawn(binPath, process.argv.slice(2), { stdio: 'inherit' }) child.on('exit', code => process.exit(code ?? 1)) child.on('error', err => { console.error(`[mizan-generate] failed to spawn ${binPath}: ${err.message}`) process.exit(1) })