Refresh stored rule template/display when their computed form drifts

They are outside the rule key, so a format change (like the one in the
previous commit) silently disabled rename detection for existing records.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Christopher Monsanto
2026-08-15 22:34:11 -04:00
parent 2d83f4a16f
commit 44fb49a96f
2 changed files with 33 additions and 1 deletions

View File

@@ -211,6 +211,22 @@ export class BuildDb {
this.db.prepare('DELETE FROM rules WHERE id = ?').run(id);
}
// template/display are pure functions of the rule declaration but are not
// part of the rule key; refresh stored values that have drifted (e.g. the
// template format changed in a newer version of this tool), otherwise
// rename detection quietly stops matching older records.
refreshRuleMeta(entries : {id : bigint, template : string, display : string | null}[]) : void {
if (entries.length === 0) {
return;
}
const update = this.db.prepare('UPDATE rules SET template = ?, display = ? WHERE id = ?');
this.db.transaction(() => {
for (const e of entries) {
update.run(e.template, e.display, e.id);
}
})();
}
close() : void {
this.db.pragma('wal_checkpoint(TRUNCATE)');
this.db.close();

View File

@@ -100,14 +100,30 @@ async function main() : Promise<number> {
}
return st;
};
const stored = db.loadStoredRules();
const plan = computePlan({
current: rules,
stored: db.loadStoredRules(),
stored,
hashes,
statOutput,
adopt: Boolean(opts.adopt),
});
// Keep stored template/display in sync for key-matched rules; they are
// outside the key, so e.g. a template format change in this tool would
// otherwise silently disable rename detection for old records.
if (!dryRun) {
const storedByKey = new Map(stored.map(s => [s.key, s]));
const staleMeta = [];
for (const decl of rules) {
const s = storedByKey.get(decl.key);
if (s !== undefined && (s.template !== decl.template || s.display !== decl.display)) {
staleMeta.push({id: s.id, template: decl.template, display: decl.display});
}
}
db.refreshRuleMeta(staleMeta);
}
const staleOutputs = [];
const currentOutputs = new Set(rules.flatMap(r => r.outputs));
for (const s of plan.stale) {