LOT Q0 : socle du démonstrateur Quelque part en 2035
Scaffold Vite + TypeScript + Three.js (scène vide : sol + boîte, marqueur de build), store et encodage de l'état dans l'URL (5 tests), lint de frontières entre modules, pipeline d'extraction Rhino (graine du 26/09) et première géométrie v0, deploy.sh statique (releases + lien symbolique + smoke), AGENTS.md, RUNBOOK, licences MIT + CC BY-SA 4.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env node
|
||||
// Lint de frontières entre modules (ARCHITECTURE §4). Échoue si un import franchit une frontière interdite.
|
||||
// ui/ ne doit importer ni gen/ ni fx/ ni horscamp/ (il passe par core/state)
|
||||
// gen/ fx/ horscamp/ ne doivent pas importer ui/
|
||||
// personne n'importe main.ts
|
||||
import { readdirSync, readFileSync, statSync } from 'node:fs';
|
||||
import { join, relative, dirname, resolve } from 'node:path';
|
||||
|
||||
const racine = resolve(new URL('..', import.meta.url).pathname, 'src');
|
||||
const interdits = {
|
||||
ui: ['gen', 'fx', 'horscamp'],
|
||||
gen: ['ui'],
|
||||
fx: ['ui'],
|
||||
horscamp: ['ui'],
|
||||
core: ['ui', 'gen', 'fx', 'horscamp'],
|
||||
content: ['ui', 'gen', 'fx', 'horscamp'],
|
||||
};
|
||||
|
||||
function fichiers(d) {
|
||||
return readdirSync(d).flatMap((n) => {
|
||||
const p = join(d, n);
|
||||
return statSync(p).isDirectory() ? fichiers(p) : p.endsWith('.ts') ? [p] : [];
|
||||
});
|
||||
}
|
||||
|
||||
let erreurs = 0;
|
||||
for (const f of fichiers(racine)) {
|
||||
const rel = relative(racine, f);
|
||||
const module = rel.includes('/') ? rel.split('/')[0] : '(racine)';
|
||||
const src = readFileSync(f, 'utf8');
|
||||
for (const m of src.matchAll(/from\s+['"](\.[^'"]+)['"]/g)) {
|
||||
const cible = relative(racine, resolve(dirname(f), m[1]));
|
||||
const moduleCible = cible.includes('/') ? cible.split('/')[0] : cible.replace(/\.ts$/, '');
|
||||
if (moduleCible === 'main' && rel !== 'main.ts') {
|
||||
console.error(`✗ ${rel} importe main.ts`);
|
||||
erreurs++;
|
||||
}
|
||||
if ((interdits[module] ?? []).includes(moduleCible)) {
|
||||
console.error(`✗ ${rel} (${module}) importe ${cible} (${moduleCible}) : frontière interdite`);
|
||||
erreurs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (erreurs) {
|
||||
console.error(`${erreurs} franchissement(s) de frontière.`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('frontières respectées');
|
||||
Reference in New Issue
Block a user