mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
Script resolved paths from repo root; inside the frontend Docker build (context = app/frontend) it scanned /docs and died on ENOENT, breaking the compose smoke job. Resolve from the frontend dir and fall back to the committed snapshot when the docs tree is absent. Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
69 lines
2.7 KiB
JavaScript
69 lines
2.7 KiB
JavaScript
// Bundles the repository docs/ tree into a generated TS module so the docs
|
|
// browser renders instantly and offline. The GitHub sync layer refreshes it
|
|
// at runtime when network is available.
|
|
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
import { join, relative } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const frontendRoot = join(fileURLToPath(new URL('.', import.meta.url)), '..');
|
|
const root = join(frontendRoot, '..', '..');
|
|
const docsDir = join(root, 'docs');
|
|
const outFile = join(frontendRoot, 'src/generated/docs-snapshot.ts');
|
|
|
|
// The published frontend image builds with only app/frontend as its Docker
|
|
// context, so the repo docs tree is absent there — reuse the committed
|
|
// snapshot instead of failing on ENOENT.
|
|
if (!existsSync(docsDir)) {
|
|
if (!existsSync(outFile)) {
|
|
console.error('docs snapshot: docs/ missing and no committed snapshot to reuse');
|
|
process.exit(1);
|
|
}
|
|
console.warn('docs snapshot: docs/ not found, reusing committed snapshot');
|
|
process.exit(0);
|
|
}
|
|
|
|
// Directories that are internal working notes rather than user documentation.
|
|
const SKIP_DIRS = new Set(['archive', 'design', 'superpowers']);
|
|
|
|
function walk(dir) {
|
|
const entries = [];
|
|
for (const name of readdirSync(dir)) {
|
|
const full = join(dir, name);
|
|
const stat = statSync(full);
|
|
if (stat.isDirectory()) {
|
|
if (!SKIP_DIRS.has(name)) entries.push(...walk(full));
|
|
} else if (name.toLowerCase().endsWith('.md')) {
|
|
entries.push(full);
|
|
}
|
|
}
|
|
return entries;
|
|
}
|
|
|
|
function titleOf(markdown, fallback) {
|
|
const match = markdown.match(/^#\s+(.+)$/m);
|
|
if (match) return match[1].replace(/[#*`]/g, '').trim();
|
|
return fallback
|
|
.replace(/\.md$/i, '')
|
|
.replace(/[-_]+/g, ' ')
|
|
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
}
|
|
|
|
const files = walk(docsDir).sort();
|
|
const docs = files.map((full) => {
|
|
const rel = relative(docsDir, full).replace(/\\/g, '/');
|
|
const markdown = readFileSync(full, 'utf8');
|
|
const section = rel.includes('/') ? rel.split('/')[0] : 'docs';
|
|
return {
|
|
path: rel,
|
|
section,
|
|
title: titleOf(markdown, rel.split('/').pop() ?? rel),
|
|
markdown,
|
|
};
|
|
});
|
|
|
|
const banner = `/**\n * Auto-generated by scripts/generate-docs-snapshot.mjs.\n * Bundled copy of the repository docs tree — the offline fallback for the\n * docs browser. Regenerate with \`npm run generate:docs\`.\n */\n\nexport type BundledDoc = {\n path: string;\n section: string;\n title: string;\n markdown: string;\n};\n\n`;
|
|
|
|
mkdirSync(join(outFile, '..'), { recursive: true });
|
|
writeFileSync(outFile, `${banner}export const bundledDocs: BundledDoc[] = ${JSON.stringify(docs, null, 2)};\n`);
|
|
console.log(`docs snapshot: ${docs.length} files → ${relative(root, outFile)}`);
|