mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
The desktop kind registry was a hand-maintained mirror of crates/buzz-core/src/kind.rs: 55 constants vs 121 upstream, no drift check, and 10 names that diverged from their canonical buzz-core spelling. Silent drift here means the client simply doesn't recognize an event kind — no error, just missing behavior (launch-readiness review, cross-cutting finding #1). This makes buzz-core the single source of truth for kind numbers: - desktop/scripts/generate-kinds.mjs parses kind.rs (read-only input) and emits kinds.generated.ts — byte-stable output, source order preserved, first doc-comment line carried over, do-not-edit header. - kinds.ts re-exports the full generated registry, keeps the 10 legacy desktop-local names as aliases of the canonical constants (values can no longer drift), and retains the desktop-specific derived kind sets unchanged. - pnpm check now runs generate-kinds.mjs --check, which fails CI on any drift between kinds.generated.ts and kind.rs — including manual edits to the generated file. No values changed: audit of all 55 pre-existing constants found zero name/value mismatches against kind.rs (10 naming aliases only). Behavior is unchanged; all existing imports keep working. Part of the launch-readiness complexity drip (clients queue #1). Next up: extend the same generation to mobile's EventKind. Co-authored-by: Bradley Axen <baxen@squareup.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
109 lines
3.6 KiB
JavaScript
109 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
|
// Generates desktop/src/shared/constants/kinds.generated.ts from
|
|
// crates/buzz-core/src/kind.rs — the authoritative Buzz kind registry.
|
|
//
|
|
// Usage:
|
|
// node scripts/generate-kinds.mjs # write the generated file
|
|
// node scripts/generate-kinds.mjs --check # fail (exit 1) if the committed
|
|
// # file differs from regenerated
|
|
// # output (drift or hand-edits)
|
|
//
|
|
// kind.rs is read-only input; never edit it from here. Output is byte-stable:
|
|
// constants are emitted in kind.rs source order with the first doc-comment
|
|
// line carried over.
|
|
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const desktopDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
const repoRoot = dirname(desktopDir);
|
|
const sourcePath = join(repoRoot, "crates", "buzz-core", "src", "kind.rs");
|
|
const outputPath = join(
|
|
desktopDir,
|
|
"src",
|
|
"shared",
|
|
"constants",
|
|
"kinds.generated.ts",
|
|
);
|
|
|
|
function parseKinds(rustSource) {
|
|
const lines = rustSource.split("\n");
|
|
const kinds = [];
|
|
let docFirstLine = null;
|
|
for (const line of lines) {
|
|
const doc = line.match(/^\s*\/\/\/\s?(.*)$/);
|
|
if (doc) {
|
|
// Keep only the first line of each doc block as the TS comment.
|
|
if (docFirstLine === null) docFirstLine = doc[1].trim();
|
|
continue;
|
|
}
|
|
const konst = line.match(/^pub const (KIND_\w+): u32 = (\d+);/);
|
|
if (konst) {
|
|
kinds.push({ name: konst[1], value: konst[2], doc: docFirstLine });
|
|
docFirstLine = null;
|
|
continue;
|
|
}
|
|
// Any non-doc line (blank, attribute, other item) ends a doc block.
|
|
docFirstLine = null;
|
|
}
|
|
return kinds;
|
|
}
|
|
|
|
function render(kinds) {
|
|
const header = `// GENERATED FILE — DO NOT EDIT.
|
|
//
|
|
// Generated from crates/buzz-core/src/kind.rs (the authoritative Buzz kind
|
|
// registry) by desktop/scripts/generate-kinds.mjs. To change a kind number or
|
|
// add a kind, edit kind.rs and re-run:
|
|
//
|
|
// node scripts/generate-kinds.mjs
|
|
//
|
|
// CI runs \`node scripts/generate-kinds.mjs --check\` (via \`pnpm check\`) and
|
|
// fails on any drift between this file and kind.rs, including manual edits
|
|
// to this file.
|
|
`;
|
|
const body = kinds
|
|
.map(({ name, value, doc }) => {
|
|
const comment = doc ? `/** ${doc} */\n` : "";
|
|
return `${comment}export const ${name} = ${value};\n`;
|
|
})
|
|
.join("");
|
|
return `${header}\n${body}`;
|
|
}
|
|
|
|
const kinds = parseKinds(readFileSync(sourcePath, "utf8"));
|
|
if (kinds.length === 0) {
|
|
console.error(
|
|
`generate-kinds: parsed 0 constants from ${sourcePath} — parser is broken or kind.rs moved`,
|
|
);
|
|
process.exit(1);
|
|
}
|
|
const generated = render(kinds);
|
|
|
|
if (process.argv.includes("--check")) {
|
|
let committed = null;
|
|
try {
|
|
committed = readFileSync(outputPath, "utf8");
|
|
} catch {
|
|
console.error(
|
|
`generate-kinds --check: ${outputPath} is missing; run node scripts/generate-kinds.mjs`,
|
|
);
|
|
process.exit(1);
|
|
}
|
|
if (committed !== generated) {
|
|
console.error(
|
|
"generate-kinds --check: kinds.generated.ts is out of sync with crates/buzz-core/src/kind.rs.\n" +
|
|
"Re-run `node scripts/generate-kinds.mjs` from desktop/ and commit the result.\n" +
|
|
"(If you edited kinds.generated.ts by hand: don't — edit kind.rs instead.)",
|
|
);
|
|
process.exit(1);
|
|
}
|
|
console.log(`generate-kinds --check: OK (${kinds.length} constants in sync)`);
|
|
} else {
|
|
writeFileSync(outputPath, generated);
|
|
console.log(
|
|
`generate-kinds: wrote ${kinds.length} constants to ${outputPath}`,
|
|
);
|
|
}
|