Skip to content

Instantly share code, notes, and snippets.

@justsml
Last active July 1, 2020 23:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justsml/ed1dcd273b45952e4b5efdcc9d6baefc to your computer and use it in GitHub Desktop.
Save justsml/ed1dcd273b45952e4b5efdcc9d6baefc to your computer and use it in GitHub Desktop.
"use strict";
const fs = require("fs");
const fsPromises = fs.promises;
const { spawnSync } = require("child_process");
const workflows = "test";
const out = "test";
// See docs: https://fpromises.io
const FP = require('functional-promises');
/**
* Process workflow into specified format file
*/
async function compileDiagram(file, format) {
return new Promise(async function(resolve, reject) {
const result = file.replace(".mmd", "." + format);
// eslint-disable-next-line no-console
console.warn(`Compiling ${file} into ${result}`);
const child = spawnSync("node", [
"index.js",
"-i",
workflows + "/" + file,
"-o",
out + "/" + result,
"-c",
workflows + "/config.json"
], { timeout: 5000 });
const stdout = child.stdout.toString('utf8').trim()
if (stdout !== "") {
console.info(stdout)
}
const stderr = child.stderr.toString('utf8').trim()
if (stderr !== "") {
console.warn(stderr)
}
if (child.status !== 0 || child.error) {
// eslint-disable-next-line no-console
console.warn(`${file}: child process exited with code ${child.status}, error ${child.error}`);
reject(child.status);
} else {
resolve(child.status);
}
});
}
/**
* Process all workflows into files
*/
function compileAll() {
return FP.resolve(out)
.then(createPath)
.then(() => listFolderContents(workflows))
.map(processFile)
}
const processFile = file => {
return FP.all([
compileDiagram(file, "svg"),
compileDiagram(file, "png")
])
.then(([svg, png]) => {
if (file.endsWith(".mmd")) {
return png; // return last result, same as old behavior
}
return FP.resolve([svg, png])
.map(checkUnexpectedError) // FP.map docs: https://fpromises.io/#fp-map
.catch(err => Promise.reject(new Error(`Expected ${file} to fail, but it succeeded`)))
// override final result on non-mmd files
.then(() => `compiling ${file} produced an error, which is well`);
})
}
// These are just an example of the utility of named functions.
// Ideally they'd move to a shared location (i.e. utils.js) and enjoy easier testing.
const listFolderContents = dir => fsPromises.readdir(dir)
const createPath = dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
return dir
}
// Local helpers can also be tested easily!
// Export with underscore prefix `exports = {_isExpectedError: isExpectedError}` and test directly.
const isExpectedError = file => /expect-error/.test(file);
const checkUnexpectedError = result => isExpectedError(result) ? result : Promise.reject(new Error(`Unexpected Error! ${result}`));
module.exports = {
compileAll
};
if (require.main === module) {
compileAll().catch(err => {
console.warn("Compilation failed", err)
process.exit(1);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment