clawdie-ai/bootstrap/cms/clawdie-docs/scripts/sync-host-config.mjs
Operator & Codex e3ad322d3b Rename Astro docs project to clawdie-docs (Sam & Claude)
Make the docs renderer name match its purpose, add CMS_DOCS_SITE_PATH with ASTRO_SITE_PATH compatibility, and update docs publishing paths.

---
Build: pass | Tests: pass — 2372 passed (704 files)
2026-05-10 19:49:39 +02:00

114 lines
3.6 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import { spawnSync } from 'node:child_process';
function readIfExists(filePath) {
try {
return fs.readFileSync(filePath, 'utf-8');
} catch {
return null;
}
}
function writeFileAtomic(filePath, contents) {
const dir = path.dirname(filePath);
fs.mkdirSync(dir, { recursive: true });
const tmp = `${filePath}.tmp-${process.pid}`;
fs.writeFileSync(tmp, contents, { mode: 0o644 });
fs.renameSync(tmp, filePath);
}
function syncTree(sourcePath, targetPath) {
if (!fs.existsSync(sourcePath)) return false;
const sourceStat = fs.statSync(sourcePath);
if (sourceStat.isFile()) {
const sourceContents = fs.readFileSync(sourcePath, 'utf-8');
const targetContents = readIfExists(targetPath);
if (sourceContents === targetContents) return false;
writeFileAtomic(targetPath, sourceContents);
return true;
}
fs.mkdirSync(targetPath, { recursive: true });
let changed = false;
const sourceEntries = new Set(fs.readdirSync(sourcePath));
for (const entry of sourceEntries) {
const childSource = path.join(sourcePath, entry);
const childTarget = path.join(targetPath, entry);
if (syncTree(childSource, childTarget)) {
changed = true;
}
}
for (const entry of fs.readdirSync(targetPath)) {
if (sourceEntries.has(entry)) continue;
fs.rmSync(path.join(targetPath, entry), { recursive: true, force: true });
changed = true;
}
return changed;
}
const localRoot = process.cwd();
const defaultHostRoot =
localRoot.startsWith('/home/')
? `${localRoot.replace(/^\/home\//u, '/usr/home/')}-host`
: `${localRoot}-host`;
const hostRoot =
process.env.CMS_HOST_DOCS_PATH ||
process.env.CMS_HOST_SITE_PATH ||
defaultHostRoot;
if (!fs.existsSync(hostRoot)) process.exit(0);
const hostPackageJson = path.join(hostRoot, 'package.json');
const localPackageJson = path.join(localRoot, 'package.json');
const hostAstroConfig = path.join(hostRoot, 'astro.config.mjs');
const localAstroConfig = path.join(localRoot, 'astro.config.mjs');
const hostSourceAstroConfig = path.join(hostRoot, 'src', 'astro', 'astro.config.mjs');
const localSourceAstroConfig = path.join(localRoot, 'src', 'astro', 'astro.config.mjs');
const hostScriptsDir = path.join(hostRoot, 'scripts');
const localScriptsDir = path.join(localRoot, 'scripts');
const hostSrcDir = path.join(hostRoot, 'src');
const localSrcDir = path.join(localRoot, 'src');
const hostPackage = readIfExists(hostPackageJson);
if (!hostPackage) process.exit(0);
const localPackage = readIfExists(localPackageJson);
const hostConfig = readIfExists(hostAstroConfig);
const localConfig = readIfExists(localAstroConfig);
const hostSourceConfig = readIfExists(hostSourceAstroConfig);
const localSourceConfig = readIfExists(localSourceAstroConfig);
if (localPackage !== hostPackage) {
writeFileAtomic(localPackageJson, hostPackage);
}
if (hostConfig && localConfig !== hostConfig) {
writeFileAtomic(localAstroConfig, hostConfig);
}
if (hostSourceConfig && localSourceConfig !== hostSourceConfig) {
writeFileAtomic(localSourceAstroConfig, hostSourceConfig);
}
const scriptsChanged = syncTree(hostScriptsDir, localScriptsDir);
const srcChanged = syncTree(hostSrcDir, localSrcDir);
const sourceChanged = scriptsChanged || srcChanged;
if (localPackage !== hostPackage || localConfig !== hostConfig || localSourceConfig !== hostSourceConfig) {
const result = spawnSync('npm', ['install'], {
stdio: 'inherit',
cwd: localRoot,
env: process.env,
});
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
if (sourceChanged) {
console.log('Synced Astro source tree from host mount');
}