diff --git a/package.json b/package.json index 6f3bb9f..a8c62de 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "falsify:spatial": "node scripts/spatial/spatial-falsify.mjs out", "check:spatial-sync": "node scripts/spatial-sync.mjs --check", "check:illustrations": "node scripts/check-illustrations.mjs", - "check:streets": ".venv/bin/python scripts/illustrations/build_streets.py --check", - "build:streets": ".venv/bin/python scripts/illustrations/build_streets.py", + "check:streets": "node scripts/run-streets.mjs --check", + "build:streets": "node scripts/run-streets.mjs", "check:rules": "node scripts/authoring/build-rules.mjs --check" }, "dependencies": { diff --git a/scripts/run-streets.mjs b/scripts/run-streets.mjs new file mode 100644 index 0000000..650a0f4 --- /dev/null +++ b/scripts/run-streets.mjs @@ -0,0 +1,28 @@ +/** + * Run the street-scene builder with the interpreter the illustration gate + * already uses. + * + * CI installs Pillow and NumPy into the setup-python interpreter and never + * creates a project .venv. A script that calls `.venv/bin/python` exits 127 + * before the gate can measure a single picture, which is how `npm run verify` + * went red on the commit that added the streets. The order is the one the + * illustration toolchain already documents: `PYTHON` if set, otherwise the + * project `.venv`, otherwise `python3` on PATH. + */ +import { spawnSync } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { illustrationPython } from "./check-illustrations.mjs"; + +const script = path.join( + path.dirname(fileURLToPath(import.meta.url)), + "illustrations", + "build_streets.py", +); +const py = illustrationPython(); +const done = spawnSync(py, [script, ...process.argv.slice(2)], { stdio: "inherit" }); +if (done.error) { + console.error(`could not run ${py}: ${done.error.message}`); + process.exit(1); +} +process.exit(done.status ?? 1); diff --git a/tests/streets.test.ts b/tests/streets.test.ts index 1e1bc9e..8baa077 100644 --- a/tests/streets.test.ts +++ b/tests/streets.test.ts @@ -49,6 +49,17 @@ test("five pages stand in a Bangkok street, and each drawing appears once", () = } }); +test("the street gate resolves Python the way CI installs it", () => { + // setup-python puts Pillow on `python3` and does not create `.venv`. + // A script that names `.venv/bin/python` dies with exit 127, and the + // byte check never runs. The runner must share the illustration gate's + // resolver: PYTHON, then .venv, then python3 on PATH. + const pkg = JSON.parse(read("/package.json")); + assert.equal(pkg.scripts["check:streets"], "node scripts/run-streets.mjs --check"); + assert.equal(pkg.scripts["build:streets"], "node scripts/run-streets.mjs"); + assert.match(read("/scripts/run-streets.mjs"), /illustrationPython\(\)/); +}); + test("every street the app names is a file that ships", () => { for (const [, src] of Object.entries(artMap())) { if (!src.includes("/illustrations/scene-")) continue;