check / check (push) Successful in 33s
src/index.ts imports package.json for VERSION and bin/quak.ts passes VERSION to commander, so package.json is the only place the version is written. tsc copies package.json to dist/package.json, so the import resolves from the built output; script/build runs the built CLI with --version to prove it. A test checks VERSION and quak --version against package.json. Model: opus-5-5
69 lines
2.2 KiB
Python
Executable File
69 lines
2.2 KiB
Python
Executable File
#!/bin/sh
|
|
# script/build: compile the TypeScript sources into dist/, then verify that
|
|
# the artifacts package.json advertises are among the files the compiler
|
|
# actually wrote. tsc reports success by exit status alone and knows nothing
|
|
# about the manifest, so without this step a green build can still ship a
|
|
# package whose main, types or bin resolve to nothing. Our own extension to
|
|
# scripts-to-rule-them-all.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
# Reads package.json, requires every declared entrypoint to exist, requires
|
|
# each bin entry to have kept its shebang, and makes the bin entries
|
|
# executable: tsc copies the shebang through but not the mode bits, and an
|
|
# installed CLI has to be runnable.
|
|
verify_entrypoints() {
|
|
node -e '
|
|
const { readFileSync, statSync, chmodSync } = require("node:fs");
|
|
|
|
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
|
|
const bins = Object.values(pkg.bin ?? {});
|
|
const fail = (message) => {
|
|
console.error("build: " + message);
|
|
process.exit(1);
|
|
};
|
|
|
|
for (const declared of [pkg.main, pkg.types, ...bins]) {
|
|
if (!declared) continue;
|
|
try {
|
|
statSync(declared);
|
|
} catch {
|
|
fail("package.json declares " + declared + ", which the build did not produce");
|
|
}
|
|
console.log("build: verified " + declared);
|
|
}
|
|
|
|
for (const bin of bins) {
|
|
const firstLine = readFileSync(bin, "utf-8").split("\n")[0];
|
|
if (!firstLine.startsWith("#!")) {
|
|
fail(bin + " lost its shebang, so it cannot be executed directly");
|
|
}
|
|
chmodSync(bin, 0o755);
|
|
console.log("build: " + bin + " is executable (" + firstLine + ")");
|
|
}
|
|
'
|
|
}
|
|
|
|
# src/index.ts imports ../package.json for the version, which tsc copies to
|
|
# dist/package.json. Running the built CLI proves that import resolves from
|
|
# dist/ and reports the version package.json declares.
|
|
verify_version() {
|
|
built="$(node dist/bin/quak.js --version)"
|
|
declared="$(node -p 'require("./package.json").version')"
|
|
if [ "$built" != "$declared" ]; then
|
|
echo "build: dist/bin/quak.js reports $built, package.json declares $declared" >&2
|
|
exit 1
|
|
fi
|
|
echo "build: dist/bin/quak.js reports version $built"
|
|
}
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
yarn run tsc
|
|
verify_entrypoints
|
|
verify_version
|
|
}
|
|
|
|
main "$@"
|