Pinscope open-source core
Agentic schematic validation: datasheet extraction via Claude Console Skills, netlist/BOM design graph, per-IC direct datasheet review with page citations, capacitor derating, Next.js report UI. Extracted from the Pinscope cloud codebase. Auth and billing live in the private gateway repo behind stable seams (billing_hook.py, adapter files listed in CLAUDE.md).
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Single source of truth for the app version: content/changelog.md.
|
||||
*
|
||||
* Parses the topmost `## X.Y.Z — <date>` heading and propagates it to:
|
||||
* - src/lib/version.ts (APP_VERSION, shown in the UI sidebar)
|
||||
* - package.json ("version" field)
|
||||
*
|
||||
* Runs automatically via the `predev` / `prebuild` npm hooks, so the
|
||||
* sidebar version, package.json, and the changelog can never drift.
|
||||
* To cut a release, just add a new `## X.Y.Z — <date>` section at the
|
||||
* top of content/changelog.md.
|
||||
*/
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, join } from "node:path";
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const changelogPath = join(root, "content", "changelog.md");
|
||||
const versionTsPath = join(root, "src", "lib", "version.ts");
|
||||
const pkgPath = join(root, "package.json");
|
||||
|
||||
const changelog = readFileSync(changelogPath, "utf-8");
|
||||
const match = changelog.match(
|
||||
/^##\s+(\d+\.\d+\.\d+)(?:\s+[—-]\s+(\d{4}-\d{2}-\d{2}))?/m,
|
||||
);
|
||||
if (!match) {
|
||||
console.error(
|
||||
`[sync-version] No "## X.Y.Z" heading found in ${changelogPath}`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
const version = match[1];
|
||||
const versionDate = match[2] ?? "";
|
||||
|
||||
// --- src/lib/version.ts (generated; do not edit by hand) ---------------
|
||||
const versionTs = `// AUTO-GENERATED by scripts/sync-version.mjs from content/changelog.md.
|
||||
// Do not edit by hand — change the top "## X.Y.Z" heading in the changelog.
|
||||
export const APP_VERSION = "${version}";
|
||||
export const APP_VERSION_DATE = "${versionDate}";
|
||||
`;
|
||||
let tsChanged = false;
|
||||
try {
|
||||
tsChanged = readFileSync(versionTsPath, "utf-8") !== versionTs;
|
||||
} catch {
|
||||
tsChanged = true;
|
||||
}
|
||||
if (tsChanged) writeFileSync(versionTsPath, versionTs);
|
||||
|
||||
// --- package.json "version" -------------------------------------------
|
||||
const pkgRaw = readFileSync(pkgPath, "utf-8");
|
||||
const pkg = JSON.parse(pkgRaw);
|
||||
const pkgChanged = pkg.version !== version;
|
||||
if (pkgChanged) {
|
||||
pkg.version = version;
|
||||
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
||||
}
|
||||
|
||||
if (tsChanged || pkgChanged) {
|
||||
console.log(
|
||||
`[sync-version] Synced to ${version} (` +
|
||||
`${tsChanged ? "version.ts" : ""}` +
|
||||
`${tsChanged && pkgChanged ? " + " : ""}` +
|
||||
`${pkgChanged ? "package.json" : ""}).`,
|
||||
);
|
||||
} else {
|
||||
console.log(`[sync-version] Already at ${version}.`);
|
||||
}
|
||||
Reference in New Issue
Block a user