import { dirname, relative, join } from "node:path" import { existsSync } from "node:fs" import { type RegimeConfig, findRegimeConfigs, resolveTemplateChain, getStrategy, interpolate, readFileSync, diffJson, mergeTemplateJsonFiles, } from "./shared" const red = Bun.color("red", "ansi") const orange = Bun.color("orange", "ansi") const green = Bun.color("green", "ansi") const purple = Bun.color("purple", "ansi") const reset = "\x1b[0m" export async function check(targetDir: string): Promise { const rcFiles = await findRegimeConfigs(targetDir) if (rcFiles.length === 0) { console.log("No regime.config.json files found.") return } for (const rcFile of rcFiles) { const rcDir = dirname(rcFile) const relDir = relative(targetDir, rcDir) || "." console.log(`\n${purple}${relDir}/${reset}`) const rc: RegimeConfig = JSON.parse(readFileSync(rcFile)) const templateNames = Array.isArray(rc.templates) ? rc.templates : [rc.templates] const vars = rc.vars ?? {} const { files, patterns } = resolveTemplateChain(templateNames) if (files.size === 0) { console.log(" (no template files)") continue } let synced = true for (const [relPath, templatePaths] of files) { const targetPath = join(rcDir, relPath) const strategy = getStrategy(relPath, patterns) if (!existsSync(targetPath)) { console.log(` ${relPath}: ${red}missing${reset}`) synced = false continue } const existingContent = readFileSync(targetPath) if (strategy === "merge json") { try { const templateObj = mergeTemplateJsonFiles(templatePaths, vars, relPath) const existingObj = JSON.parse(existingContent) const diffs = diffJson(templateObj, existingObj) if (diffs.length > 0) { synced = false console.log(` ${relPath}:`) for (const d of diffs) { const exp = JSON.stringify(d.expected) const act = d.actual === undefined ? `${red}missing${reset}` : `${orange}${JSON.stringify(d.actual)}${reset}` console.log(` ${d.field}: ${act} -> ${green}${exp}${reset}`) } } } catch (e) { console.log(` ${relPath}: ${red}failed to parse JSON${reset} - ${e}`) synced = false } } else if (strategy === "overwrite") { const templateContent = interpolate(readFileSync(templatePaths[templatePaths.length - 1]), vars, relPath) if (existingContent !== templateContent) { console.log(` ${relPath}: ${orange}differs${reset}`) synced = false } } } if (synced) { console.log(` ${green}in sync${reset}`) } } }