97 lines
2.5 KiB
JavaScript
Executable File
97 lines
2.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import indentString from "indent-string";
|
|
import chokidar from "chokidar";
|
|
import chalk from "chalk";
|
|
import { Command } from "commander";
|
|
import glob from "glob";
|
|
|
|
const processFile = (fileName, seen = []) => {
|
|
const normalizedFileName = path.resolve(fileName);
|
|
if (seen.includes(normalizedFileName)) {
|
|
throw new Error(`Recursive dependency for file ${fileName}`);
|
|
}
|
|
|
|
const fileContents = fs.readFileSync(fileName, "utf-8");
|
|
if (!fileName.endsWith(".squiggleU")) {
|
|
return fileContents;
|
|
}
|
|
|
|
const regex = /\@import\(\s*([^)]+?)\s*\)/g;
|
|
const matches = Array.from(fileContents.matchAll(regex)).map((r) =>
|
|
r[1].split(/\s*,\s*/)
|
|
);
|
|
const newContent = fileContents.replaceAll(regex, "");
|
|
const appendings = [];
|
|
|
|
matches.forEach((r) => {
|
|
const importFileName = r[0];
|
|
const rename = r[1];
|
|
const item = fs.statSync(importFileName);
|
|
if (item.isFile()) {
|
|
const data = processFile(importFileName, [...seen, normalizedFileName]);
|
|
if (data) {
|
|
const importString = `${rename} = {\n${indentString(data, 2)}\n}\n`;
|
|
appendings.push(importString);
|
|
}
|
|
} else {
|
|
console.log(
|
|
chalk.red(`Import Error`) +
|
|
`: ` +
|
|
chalk.cyan(importFileName) +
|
|
` not found in file ` +
|
|
chalk.cyan(fileName) +
|
|
`. Make sure the @import file names all exist in this repo.`
|
|
);
|
|
}
|
|
});
|
|
const imports = appendings.join("\n");
|
|
|
|
const newerContent = imports.concat(newContent);
|
|
return newerContent;
|
|
};
|
|
|
|
const run = (fileName) => {
|
|
const content = processFile(fileName);
|
|
const parsedPath = path.parse(path.resolve(fileName));
|
|
const newFilename = `${parsedPath.dir}/${parsedPath.name}.squiggle`;
|
|
fs.writeFileSync(newFilename, content);
|
|
console.log(chalk.cyan(`Updated ${fileName} -> ${newFilename}`));
|
|
};
|
|
|
|
const compile = () => {
|
|
glob("**/*.squiggleU", (_err, files) => {
|
|
files.forEach(run);
|
|
});
|
|
};
|
|
|
|
const watch = () => {
|
|
chokidar
|
|
.watch("**.squiggleU")
|
|
.on("ready", () => console.log(chalk.green("Ready!")))
|
|
.on("change", (event, _) => {
|
|
run(event);
|
|
});
|
|
};
|
|
|
|
const program = new Command();
|
|
|
|
program
|
|
.name("squiggle-utils")
|
|
.description("CLI to transform squiggle files with @imports")
|
|
.version("0.0.1");
|
|
|
|
program
|
|
.command("watch")
|
|
.description("watch files and compile on the fly")
|
|
.action(watch);
|
|
|
|
program
|
|
.command("compile")
|
|
.description("compile all .squiggleU files into .squiggle files")
|
|
.action(compile);
|
|
|
|
program.parse();
|