clone of repo on github
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

84 lines
2.5 KiB

#!/usr/bin/env -S deno run --allow-read --allow-write
import { dirname, resolve } from "jsr:@std/path";
/** Read and parse JSON */
async function readJson(p: string) {
try {
const txt = await Deno.readTextFile(p);
return JSON.parse(txt);
} catch (e) {
console.error(`Failed to read JSON: ${p}\n${e.message}`);
Deno.exit(1);
}
}
/** Ensure parent directory exists */
async function ensureDir(filePath: string) {
await Deno.mkdir(dirname(filePath), { recursive: true });
}
/** File exists? */
async function exists(p: string) {
try {
await Deno.lstat(p);
return true;
} catch (e) {
if (e instanceof Deno.errors.NotFound) return false;
throw e;
}
}
/** Write file if changed; return action marker */
async function writeFile(p: string, content: string) {
await ensureDir(p);
const had = await exists(p);
if (had) {
const current = await Deno.readTextFile(p);
if (current === content) return "skip" as const;
}
await Deno.writeTextFile(p, content);
return had ? ("update" as const) : ("create" as const);
}
/** Shallow-merge package.json fields */
function mergePackage(pkg: any, merge: any) {
const next = { ...pkg };
for (const key of ["scripts", "dependencies", "devDependencies"]) {
if (merge?.[key]) next[key] = { ...(pkg[key] || {}), ...merge[key] };
}
return next;
}
async function main() {
const manifestPath = Deno.args[0];
if (!manifestPath) {
console.error("Usage: deno run --allow-read --allow-write scripts/scaffold.ts <manifest.json>");
Deno.exit(1);
}
const manifest = await readJson(manifestPath);
// Optional: merge package.json if present
const pkgPath = resolve(Deno.cwd(), "package.json");
if (manifest.package?.merge && (await exists(pkgPath))) {
const pkg = await readJson(pkgPath);
const merged = mergePackage(pkg, manifest.package.merge);
await Deno.writeTextFile(pkgPath, JSON.stringify(merged, null, 2) + "\n");
console.log("✓ package.json merged");
} else if (manifest.package?.merge) {
console.log("• package.json not found — skipping merge");
}
// Write files from manifest
const files = manifest.files ?? [];
for (const f of files) {
const out = resolve(Deno.cwd(), String(f.path));
const action = await writeFile(out, String(f.content ?? ""));
const marker = action === "skip" ? "•" : action === "update" ? "↻" : "✓";
console.log(`${marker} ${f.path}`);
}
console.log("\nDone.");
}
if (import.meta.main) main();