Update Docs

This commit is contained in:
Raven Scott
2026-04-06 06:44:15 -04:00
parent 6d0d1b8049
commit f0fb05274b
21 changed files with 573 additions and 17 deletions
+136
View File
@@ -0,0 +1,136 @@
#!/usr/bin/env node
/**
* Validates ```mermaid fenced blocks in Markdown by rendering with @mermaid-js/mermaid-cli.
*
* - Skips unless `BARE_OS_VALIDATE_MERMAID=1` or `GITHUB_ACTIONS=true` (keeps local `pretest` fast).
* - Installs mermaid-cli once into a temp directory (requires network when not cached).
*
* Used by `.github/workflows/docs-mermaid-smoke.yml` (workflow_dispatch + weekly schedule).
*/
import { execFileSync, spawnSync } from 'node:child_process'
import fs from 'node:fs'
import path from 'node:path'
import os from 'node:os'
import { fileURLToPath } from 'node:url'
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
const SHOULD_RUN =
process.env.BARE_OS_VALIDATE_MERMAID === '1' || process.env.GITHUB_ACTIONS === 'true'
if (!SHOULD_RUN) {
console.log(
'validate-mermaid-syntax: skip (set BARE_OS_VALIDATE_MERMAID=1 or run in GitHub Actions)'
)
process.exit(0)
}
const GLOBS = ['docs', 'handbook', 'developer-guide', 'users-manual', 'scripts', 'packages']
const ROOT_MD = ['README.md', 'DOCUMENTATION.md']
const SKIP_FILES = new Set(['packages/bare-os-bare-libs/README.kernel-lib-bare.md'])
function isSkippedPath(relFromRoot) {
const norm = relFromRoot.split(path.sep).join('/')
return norm === 'packages/bare-os-seeder/kernel' || norm.startsWith('packages/bare-os-seeder/kernel/')
}
function walkMd(dir) {
const abs = path.join(root, dir)
if (!fs.existsSync(abs)) return []
const out = []
const st = fs.statSync(abs)
if (st.isFile() && abs.endsWith('.md')) {
out.push(abs)
return out
}
if (!st.isDirectory()) return out
for (const ent of fs.readdirSync(abs, { withFileTypes: true })) {
if (ent.name === 'node_modules' || ent.name === '.git') continue
const p = path.join(abs, ent.name)
const relFromRoot = p.slice(root.length + 1)
if (isSkippedPath(relFromRoot)) continue
if (ent.isDirectory()) out.push(...walkMd(relFromRoot))
else if (ent.isFile() && ent.name.endsWith('.md')) out.push(p)
}
return out
}
/** @param {string} file */
function extractMermaidBlocks(file) {
const text = fs.readFileSync(file, 'utf8')
const re = /```mermaid\n([\s\S]*?)```/g
/** @type {string[]} */
const blocks = []
let m
while ((m = re.exec(text))) {
const body = m[1].trimEnd()
if (body.length) blocks.push(body)
}
return blocks
}
/** @type {string[]} */
const files = []
for (const d of GLOBS) files.push(...walkMd(d))
for (const name of ROOT_MD) {
const p = path.join(root, name)
if (fs.existsSync(p)) files.push(p)
}
/** @type {{ file: string, index: number, body: string }[]} */
const diagrams = []
for (const file of files) {
const rel = path.relative(root, file)
if (SKIP_FILES.has(rel.split(path.sep).join('/'))) continue
const blocks = extractMermaidBlocks(file)
blocks.forEach((body, i) => diagrams.push({ file: rel, index: i, body }))
}
if (diagrams.length === 0) {
console.log('validate-mermaid-syntax: no mermaid blocks found')
process.exit(0)
}
const work = fs.mkdtempSync(path.join(os.tmpdir(), 'bare-os-mmdc-'))
const npmInstall = spawnSync(
'npm',
['install', '--no-fund', '--no-audit', '@mermaid-js/[email protected]'],
{ cwd: work, stdio: 'inherit', encoding: 'utf8' }
)
if (npmInstall.status !== 0) {
console.error('validate-mermaid-syntax: npm install mermaid-cli failed')
process.exit(1)
}
const mmdc = path.join(work, 'node_modules', '.bin', 'mmdc')
if (!fs.existsSync(mmdc)) {
console.error('validate-mermaid-syntax: mmdc not found after install')
process.exit(1)
}
let failed = 0
for (let i = 0; i < diagrams.length; i++) {
const { file, index, body } = diagrams[i]
const base = `diagram-${i}`
const input = path.join(work, `${base}.mmd`)
const output = path.join(work, `${base}.svg`)
fs.writeFileSync(input, `${body}\n`, 'utf8')
try {
execFileSync(mmdc, ['-i', input, '-o', output, '-b', 'transparent'], {
stdio: ['ignore', 'pipe', 'pipe'],
encoding: 'utf8',
})
} catch (e) {
failed++
const stderr = e instanceof Error && 'stderr' in e ? String(e.stderr) : String(e)
console.error(`\n--- Mermaid render failed: ${file} block #${index + 1} ---\n${stderr}`)
}
}
if (failed > 0) {
console.error(`\nvalidate-mermaid-syntax: ${failed} of ${diagrams.length} diagram(s) failed`)
process.exit(1)
}
console.log(`validate-mermaid-syntax: OK (${diagrams.length} diagram(s))`)