UNPKG

@spongex/docbuilder

Version:

Run document generators for multiple projects

190 lines (184 loc) 5.76 kB
#!/usr/bin/env node // src/docbuilder.ts import fs from "fs"; import path from "path"; import { exec } from "child_process"; import { red, green, yellow, cyan, dim } from "kolorist"; import { __locale } from "@spongex/system-locale"; import { AsyncResolver } from "@spongex/async-resolver"; import { scriptError } from "@spongex/script-error"; var constants = { SETTINGS_FILE: `.docbuilder.config.json`, LOG_FILE: `.docbuilder.log`, OUTPUT_FOLDER: "docs" }; var loadSettings = () => { try { const settings2 = fs.readFileSync(path.join(process.cwd(), constants.SETTINGS_FILE)); return JSON.parse(settings2.toString()); } catch (error) { scriptError(`Can't find a local '${constants.SETTINGS_FILE}' configuration file.`); } }; var writeLog = (message) => { try { fs.appendFileSync(path.normalize(path.join(process.cwd(), constants.LOG_FILE)), message); } catch (error) { scriptError(error.message); } }; var verifyFolder = (folder) => { try { fs.accessSync(path.normalize(folder)); } catch (error) { try { fs.mkdirSync(folder); } catch (error2) { scriptError(error2.message); } } }; var deleteFolder = (folder) => { if (fs.existsSync(folder)) { try { fs.rmSync(folder, { recursive: true, force: true }); } catch (error) { } } }; var jobRunner = async (jobs, command, splicer, callback) => { splicer = splicer || (() => { return command; }); callback = callback || (() => { }); const runningJobs = []; jobs.forEach((job) => { runningJobs.push(new AsyncResolver()); const jobIDX = runningJobs.length - 1; const run_command = splicer(job, command); exec(run_command, { cwd: path.normalize(job.path) }, (error, stdout, stderr) => { let cmdRes; if (error) { cmdRes = { name: job.name, command: run_command, code: error.code, stdout, stderr }; runningJobs[jobIDX].reject(cmdRes); } else { cmdRes = { name: job.name, command: run_command, code: 0, stdout, stderr }; const jobOut = job.out || "docs"; try { fs.cpSync( path.join(job.path, jobOut), path.join(process.cwd(), constants.OUTPUT_FOLDER), { recursive: true } ); } catch (error2) { deleteFolder(path.join(job.path, jobOut)); cmdRes.stderr = error2.message; runningJobs[jobIDX].reject(cmdRes); } if (job.hasOwnProperty("removeold") && job.removeold) deleteFolder(path.join(job.path, jobOut)); runningJobs[jobIDX].resolve(cmdRes); } callback(error, cmdRes); }); }); let jobPromises = []; runningJobs.forEach((job) => { jobPromises.push(job.promise); }); return await Promise.allSettled(jobPromises); }; console.log(cyan(`Documentation Generation Script `)); var settings = loadSettings(); if (!settings.hasOwnProperty("generators")) scriptError("Must define documentation generators to run."); settings["jobs"].forEach((job) => { if (!job.hasOwnProperty("name") || !job.hasOwnProperty("generator") || !job.hasOwnProperty("path")) scriptError(`Invalid job format.`); }); if (settings.hasOwnProperty("log_file")) constants.LOG_FILE = settings["log_file"]; if (settings.hasOwnProperty("output_folder")) constants.OUTPUT_FOLDER = settings["output_folder"]; if (!settings["nologging"]) { console.log(dim(yellow(`Logging output to '${constants.LOG_FILE}'...`))); if (fs.existsSync(path.join(process.cwd(), constants.LOG_FILE))) { try { fs.unlinkSync(path.join(process.cwd(), constants.LOG_FILE)); } catch (error) { scriptError(`Unable to remove old log file! Verify you have write access`); } } writeLog(`Documentation Generation Script Log File `); } if (fs.existsSync(path.join(process.cwd(), constants.OUTPUT_FOLDER))) { try { fs.rmSync( path.join(process.cwd(), constants.OUTPUT_FOLDER), { recursive: true, force: true } ); } catch (error) { scriptError(`Unable to remove old documentation folder! Verify you have write access`); } } verifyFolder(path.join(process.cwd(), constants.OUTPUT_FOLDER)); var logRes = ""; console.log(`Running jobs, please wait...`); await jobRunner( settings["jobs"], "", (job) => { if (job.checkfolder) verifyFolder(path.join(process.cwd(), constants.OUTPUT_FOLDER, job.name)); let runCmd = settings["generators"][job.generator]; runCmd = runCmd.replaceAll("$PROJECT_LOCATION", job.path); runCmd = runCmd.replaceAll("$PROJECT", job.name); runCmd = runCmd.replaceAll("$OUTPUT_FOLDER", constants.OUTPUT_FOLDER); return runCmd; }, (error, cmdRes) => { logRes += `-------------------------------------------------- Job: ${cmdRes.name} -------------------------------------------------- Command: ${cmdRes.command} Return code: ${cmdRes.code} Output: ${cmdRes.stdout} Errors: ${cmdRes.stderr} `; if (error) console.log(red(` WARNING: Problems running job '${cmdRes.name}' see log for details...`)); } ).then((jobResults) => { let goodRes = jobResults.length; jobResults.forEach((job) => { if (job.status === "rejected") goodRes--; }); if (!settings["nologging"]) { writeLog(logRes + `-------------------------------------------------- `); writeLog(`${goodRes} of ${jobResults.length} jobs completed successfully at ${(/* @__PURE__ */ new Date()).toLocaleString(__locale)}`); } console.log(` ${goodRes} of ${jobResults.length} jobs completed successfully at ${(/* @__PURE__ */ new Date()).toLocaleString(__locale)}`); console.log(green(`Done! `)); }); process.exit(0);