import fs from 'node:fs' import path from 'node:path' import { spawnSync } from 'node:child_process' import { fileURLToPath } from 'node:url' const scriptDirectory = path.dirname(fileURLToPath(import.meta.url)) const pipelineDirectory = path.resolve(scriptDirectory, '..') const workspace = path.resolve(pipelineDirectory, '..') const manifestPath = path.join(pipelineDirectory, 'manifests', 'g01-background-candidates.json') const reportPath = path.join(pipelineDirectory, 'generated', 'g01-background', 'build-report.json') const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) if (manifest.schemaVersion !== 1 || manifest.page !== 'G01' || manifest.candidates?.length !== 4) { throw new Error('G01 background manifest must declare exactly four schema v1 candidates') } for (const candidate of manifest.candidates) { const source = path.resolve(workspace, candidate.master) const relative = path.relative(workspace, source) if (relative.startsWith('..') || path.isAbsolute(relative)) throw new Error(`${candidate.id} master escapes workspace`) if (!fs.existsSync(source)) throw new Error(`${candidate.id} master is missing: ${candidate.master}`) } const localPython = path.join(pipelineDirectory, '.venv', 'Scripts', 'python.exe') const python = process.env.PYTHON || (fs.existsSync(localPython) ? localPython : 'python') const result = spawnSync( python, [path.join(scriptDirectory, 'build_g01_backgrounds.py'), manifestPath, '--workspace', workspace, '--report', reportPath], { cwd: workspace, encoding: 'utf8', stdio: 'inherit' } ) if (result.error) throw new Error(`无法启动 Python(${python}):${result.error.message}`) if (result.status !== 0) process.exit(result.status ?? 1)