You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/scripts/__names-verify-diff.ts

101 lines
3.8 KiB

/**
* Gate del paso 2 (codemod D-TH.6): el diff de `generated/base.css` son
* renombres 1:1 y NADA más — cero cambios de valor.
*
* Dos formas legítimas de aparecer en el diff, y ninguna más:
*
* 1. RENOMBRE la declaración cambia de nombre; su valor, salvo las
* referencias que el propio plan reapunta, es idéntico.
* 2. REAPUNTADA la declaración conserva su nombre (típicamente un privado
* `--_c-*`) y su valor sólo cambia porque REFERENCIA un
* token renombrado.
*
* El plan se lee del registro que el codemod escribió ANTES de tocar nada:
* releer el clasificador aquí daría cero desviaciones —ya están renombradas—
* y el gate pasaría sobre el vacío.
*/
import { execSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
interface Decl {
name: string;
value: string;
}
const parse = (line: string): Decl | null => {
const m = line.slice(1).match(/^\s*(--[a-z0-9_-]+)\s*:\s*(.*?);?\s*$/);
return m ? { name: m[1], value: m[2] } : null;
};
const diff = execSync('git diff -U0 src/uix/eidos/generated/base.css', {
encoding: 'utf8',
maxBuffer: 1 << 28
}).split('\n');
const removedLines = diff.filter((l) => l.startsWith('-') && !l.startsWith('---'));
const addedLines = diff.filter((l) => l.startsWith('+') && !l.startsWith('+++'));
const plan = new Map<string, string>();
for (const r of JSON.parse(readFileSync(resolve('scripts/__names-plan.json'), 'utf8')) as Array<{
component: string;
from: string;
to: string;
}>)
plan.set(`--${r.component}-${r.from}`, `--${r.component}-${r.to}`);
const ordered = [...plan].sort((a, b) => b[0].length - a[0].length);
const applyPlan = (value: string) => {
let out = value;
for (const [from, to] of ordered)
out = out.replace(new RegExp(from.replace(/-/g, '\\-') + '(?![a-zA-Z0-9-])', 'g'), to);
return out;
};
const removed = removedLines.map(parse);
const added = addedLines.map(parse);
const unparsed = [...removed, ...added].filter((d) => d === null).length;
/** name → todos los valores añadidos bajo ese nombre. */
const addedByName = new Map<string, string[]>();
for (const a of added) if (a) addedByName.set(a.name, [...(addedByName.get(a.name) ?? []), a.value]);
let renamed = 0;
let rewired = 0;
const problems: string[] = [];
for (const r of removed) {
if (!r) continue;
const to = plan.get(r.name);
if (to) {
const vals = addedByName.get(to) ?? [];
if (vals.includes(r.value) || vals.includes(applyPlan(r.value))) renamed++;
else
problems.push(
`VALOR CAMBIÓ ${r.name} → ${to}\n antes: ${r.value}\n ahora: ${vals.join(' | ') || '(ausente)'}`
);
continue;
}
// Sin renombre: sólo vale que su valor se haya reapuntado por el plan.
const vals = addedByName.get(r.name) ?? [];
const rewiredValue = applyPlan(r.value);
if (rewiredValue !== r.value && vals.includes(rewiredValue)) rewired++;
else problems.push(`RETIRADA SIN PLAN ${r.name}: ${r.value}`);
}
/** Ningún nombre añadido puede ser una invención. */
const legalNames = new Set([...plan.values(), ...removed.filter(Boolean).map((d) => d!.name)]);
const invented = added.filter((a) => a && !legalNames.has(a.name)) as Decl[];
console.log(`líneas retiradas ${removedLines.length} · añadidas ${addedLines.length}`);
console.log(`renombres 1:1 ${renamed} / ${plan.size} planificados · reapuntadas ${rewired}`);
console.log(`sin parsear ${unparsed} · añadidos inventados ${invented.length} · problemas ${problems.length}`);
for (const p of problems.slice(0, 8)) console.log(' XX ' + p);
for (const i of invented.slice(0, 8)) console.log(' XX INVENTADO ' + i.name);
const ok =
problems.length === 0 && invented.length === 0 && unparsed === 0 && renamed === plan.size;
console.log(ok ? '\nGATE VERDE: renombres 1:1, cero cambios de valor' : '\nGATE ROJO');
process.exit(ok ? 0 : 1);

Powered by TurnKey Linux.