Files
openclaw/scripts/format-docs.mjs
2026-04-28 08:06:03 +01:00

101 lines
2.9 KiB
JavaScript

#!/usr/bin/env node
import { execFileSync, spawnSync } from "node:child_process";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { repairMintlifyAccordionIndentation } from "./lib/mintlify-accordion.mjs";
const ROOT = path.resolve(import.meta.dirname, "..");
const CHECK = process.argv.includes("--check");
const OXFMT_BIN = path.join(ROOT, "node_modules", "oxfmt", "bin", "oxfmt");
const OXFMT_CONFIG = path.join(ROOT, ".oxfmtrc.jsonc");
function docsFiles() {
const output = execFileSync("git", ["ls-files", "docs/**/*.md", "docs/**/*.mdx", "README.md"], {
cwd: ROOT,
encoding: "utf8",
});
return output.split("\n").filter(Boolean);
}
function runOxfmt(files) {
const result = spawnSync(
process.execPath,
[OXFMT_BIN, "--write", "--threads=1", "--config", OXFMT_CONFIG, ...files],
{
cwd: ROOT,
encoding: "utf8",
maxBuffer: 1024 * 1024 * 16,
},
);
if (result.status !== 0) {
const stderr = result.stderr.trim();
throw new Error(`oxfmt failed${stderr ? `:\n${stderr}` : ""}`);
}
}
function repairFiles(root, files) {
const changed = [];
for (const relativePath of files) {
const absolutePath = path.join(root, relativePath);
const raw = fs.readFileSync(absolutePath, "utf8");
const formatted = repairMintlifyAccordionIndentation(raw);
if (formatted === raw) {
continue;
}
fs.writeFileSync(absolutePath, formatted);
changed.push(relativePath);
}
return changed;
}
function copyDocsToTemp(files) {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-docs-format-"));
for (const relativePath of files) {
const source = path.join(ROOT, relativePath);
const target = path.join(tempRoot, relativePath);
fs.mkdirSync(path.dirname(target), { recursive: true });
fs.copyFileSync(source, target);
}
return tempRoot;
}
const changed = [];
const files = docsFiles();
if (CHECK) {
const tempRoot = copyDocsToTemp(files);
try {
runOxfmt(files.map((relativePath) => path.join(tempRoot, relativePath)));
repairFiles(tempRoot, files);
for (const relativePath of files) {
const raw = fs.readFileSync(path.join(ROOT, relativePath), "utf8");
const formatted = fs.readFileSync(path.join(tempRoot, relativePath), "utf8");
if (formatted !== raw) {
changed.push(relativePath);
}
}
} finally {
fs.rmSync(tempRoot, { recursive: true, force: true });
}
} else {
runOxfmt(files);
changed.push(...repairFiles(ROOT, files));
}
if (CHECK && changed.length > 0) {
console.error(`Format issues found in ${changed.length} docs file(s):`);
for (const relativePath of changed) {
console.error(`- ${relativePath}`);
}
process.exit(1);
}
if (changed.length > 0) {
console.log(`Formatted ${changed.length} docs file(s).`);
} else {
console.log(`Docs formatting clean (${files.length} files).`);
}