154 lines
4.9 KiB
TypeScript
154 lines
4.9 KiB
TypeScript
|
|
import { Issue } from "./githubType.ts";
|
|
import { copy } from "https://deno.land/std@0.136.0/fs/mod.ts";
|
|
import { readAll } from "https://deno.land/std@0.135.0/streams/mod.ts"
|
|
import { parse as argParse } from "https://deno.land/std@0.135.0/flags/mod.ts";
|
|
import {
|
|
normalize, join as pathJoin, fromFileUrl, parse as parsePath
|
|
, relative
|
|
} from "https://deno.land/std@0.135.0/path/mod.ts";
|
|
import * as Eta from "https://deno.land/x/eta@v1.12.3/mod.ts";
|
|
import { createReactive } from "./reactivity.ts";
|
|
|
|
async function readContent(path?: string): Promise<string> {
|
|
let content = "[]";
|
|
if (path) {
|
|
content = await Deno.readTextFile(path);
|
|
}
|
|
else if (!Deno.isatty(Deno.stdin.rid)) {
|
|
const decoder = new TextDecoder(undefined, { ignoreBOM: true });
|
|
const buf = await readAll(Deno.stdin);
|
|
content = decoder.decode(buf);
|
|
}
|
|
else throw new Error("No input provided. path or stdin.");
|
|
return content;
|
|
}
|
|
type printDocParam = {
|
|
target: string,
|
|
data: {
|
|
issues: Issue[]
|
|
}
|
|
};
|
|
|
|
async function printDoc(param: printDocParam, option?: {
|
|
outDir?: string
|
|
}) {
|
|
option = option ?? {};
|
|
const { target, data } = param;
|
|
const { outDir } = option;
|
|
|
|
let print: string = "";
|
|
print = await Eta.renderFile(target, data) as string;
|
|
if (outDir) {
|
|
const outPath = pathJoin(outDir, target);
|
|
await Deno.mkdir(pathJoin(outDir), { recursive: true });
|
|
await Deno.writeTextFile(outPath, print);
|
|
}
|
|
else {
|
|
console.log(print);
|
|
}
|
|
}
|
|
|
|
async function readAndPrint(args: {
|
|
issue_path?: string,
|
|
outDir?: string,
|
|
targets: string[],
|
|
}) {
|
|
const c = await readContent(args.issue_path);
|
|
const issues = JSON.parse(c) as Issue[];
|
|
issues.sort((a, b) => a.number - b.number);
|
|
for (const target of args.targets) {
|
|
await printDoc({
|
|
target: target,
|
|
data: {
|
|
issues
|
|
}
|
|
}
|
|
, {
|
|
outDir: args.outDir
|
|
});
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const parsedArg = argParse(Deno.args);
|
|
const { issue_path, outDirArg, w, watch } = parsedArg;
|
|
const watchMode = w || watch;
|
|
if (typeof issue_path !== "undefined" && typeof issue_path !== "string") {
|
|
console.log("Please provide a path to the json file.");
|
|
Deno.exit(1);
|
|
}
|
|
if (typeof outDirArg !== "undefined" && typeof outDirArg !== "string") {
|
|
console.log("Please provide a path to the output file.");
|
|
Deno.exit(1);
|
|
}
|
|
const outDir = (outDirArg ?? "build");
|
|
if (typeof watchMode !== "undefined" && typeof watchMode !== "boolean") {
|
|
console.log("Please provide a boolean value for w.");
|
|
Deno.exit(1);
|
|
}
|
|
if (watchMode && typeof issue_path === "undefined") {
|
|
console.log("Could not set watch mode without a path.");
|
|
Deno.exit(1);
|
|
}
|
|
|
|
const url = new URL(import.meta.url)
|
|
url.pathname = normalize(pathJoin(url.pathname, "..", "template"));
|
|
const viewPath = fromFileUrl(url);
|
|
Eta.configure({
|
|
views: viewPath,
|
|
"view cache": false,
|
|
});
|
|
const issuesR = await createReactive(async () => {
|
|
const c = await readContent(issue_path);
|
|
const issues = JSON.parse(c) as Issue[];
|
|
issues.sort((a, b) => a.number - b.number);
|
|
return issues;
|
|
});
|
|
|
|
const targets = ["SUMMARY.md", "overall.md", "specific.md", "intro.md", "support.md"];
|
|
|
|
const targetsR = await Promise.all(targets.map(async (t) => {
|
|
return await createReactive(() => {
|
|
return readAndPrint({ issue_path, outDir, targets:[t] });
|
|
});
|
|
}
|
|
|
|
));
|
|
issuesR.wireTo(...targetsR);
|
|
const copyOp = await createReactive(async () => {
|
|
const files = [...Deno.readDirSync(viewPath)].map(x => x.name).filter(x => !x.endsWith(".md"));
|
|
const op = files.map(x => copy(pathJoin(viewPath, x), pathJoin(outDir, x), { overwrite: true }));
|
|
await Promise.all(op);
|
|
});
|
|
|
|
if (watchMode) {
|
|
const watcher = Deno.watchFs([viewPath, issue_path as string]);
|
|
for await (const event of watcher) {
|
|
if (event.kind === "modify") {
|
|
Deno.stdout.write(
|
|
new TextEncoder().encode("\x1b[2J\x1b[0f"),
|
|
);
|
|
console.log(`reloading ${event.paths.join(", ")}`);
|
|
for (const path of event.paths) {
|
|
const p = parsePath(path);
|
|
if (p.dir === viewPath) {
|
|
if(p.ext === ".md") {
|
|
targetsR[targets.indexOf(p.base)].update();
|
|
}
|
|
else{
|
|
copyOp.update();
|
|
}
|
|
}
|
|
else if (p.base === "issues.json") {
|
|
await issuesR.update();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (import.meta.main) {
|
|
main();
|
|
} |