Watch mode support

This commit is contained in:
Endeavorance 2025-03-10 15:22:47 -04:00
parent 2032103412
commit 84b8f1c9d6
8 changed files with 157 additions and 101 deletions

View file

@ -1,101 +1,27 @@
import { parseArgs } from "node:util";
import {
serializePlaybill,
ValidatedPlaybillSchema,
} from "@proscenium/playbill";
import chalk from "chalk";
import { loadFromBinding, resolveBindingPath } from "./binding";
import { watch } from "node:fs/promises";
import { loadFromBinding, resolveBindingPath } from "./filetypes/binding";
import { usage } from "./usage";
import { CLIError, MuseError } from "./errors";
import { renderAsHTML } from "./renderers/html";
import { parseCLIArguments, type CLIArguments } from "./args";
import { fullDirname } from "./util/files";
enum ExitCode {
Success = 0,
Error = 1,
}
async function main(): Promise<number> {
// -- ARGUMENT PARSING -- //
const { values: options, positionals: args } = parseArgs({
args: Bun.argv.slice(2),
options: {
write: {
short: "w",
type: "boolean",
default: false,
},
check: {
short: "c",
type: "boolean",
default: false,
},
outfile: {
short: "o",
type: "string",
default: "playbill.json",
},
help: {
short: "h",
default: false,
type: "boolean",
},
verbose: {
short: "v",
default: false,
type: "boolean",
},
minify: {
short: "m",
default: false,
type: "boolean",
},
renderer: {
short: "r",
default: "json",
type: "string",
},
},
strict: true,
allowPositionals: true,
});
// -- HELP TEXT -- //
if (options.help) {
console.log(usage);
return ExitCode.Success;
}
// -- ARG VALIDATION -- //
if (options.check && options.write) {
throw new CLIError("Cannot use --check and --write together");
}
const VERBOSE = options.verbose;
/**
* Log a message if the vervose flag has been set
* @param msg - The message to log
*/
function verboseLog(msg: string) {
if (VERBOSE) {
console.log(chalk.dim(msg));
}
}
async function processBinding({ inputFilePath, options }: CLIArguments) {
// -- BINDING FILE -- //
const bindingPathInput = args[0] ?? "./binding.yaml";
const bindingPath = await resolveBindingPath(bindingPathInput);
verboseLog(`Building Playbill with binding: ${bindingPath}`);
const bindingPath = await resolveBindingPath(inputFilePath);
const binding = await loadFromBinding(bindingPath);
verboseLog(
`↳ Binding loaded with ${binding.includedFiles.length} associated resources`,
);
// -- VALDATE PLAYBILL -- //
verboseLog("Validating playbill");
const validatedPlaybill = ValidatedPlaybillSchema.safeParse(binding.playbill);
if (!validatedPlaybill.success) {
@ -104,8 +30,6 @@ async function main(): Promise<number> {
return ExitCode.Error;
}
verboseLog("Playbill validated");
// -- EXIT EARLY IF JUST CHECKING VALIDATION --//
if (options.check) {
console.log(chalk.green("Playbill validated successfully"));
@ -129,6 +53,7 @@ async function main(): Promise<number> {
// -- WRITE TO DISK OR STDOUT --//
if (options.write) {
await Bun.write(options.outfile, serializedPlaybill);
return ExitCode.Success;
}
@ -136,6 +61,47 @@ async function main(): Promise<number> {
return ExitCode.Success;
}
async function main(): Promise<number> {
const cliArguments = parseCLIArguments(Bun.argv.slice(2));
const { options } = cliArguments;
// -- HELP TEXT -- //
if (options.help) {
console.log(usage);
return ExitCode.Success;
}
// -- ARG VALIDATION -- //
if (options.check && options.write) {
throw new CLIError("Cannot use --check and --write together");
}
console.log(`Processing ${cliArguments.inputFilePath}`);
let lastProcessResult = await processBinding(cliArguments);
if (options.watch) {
const watchDir = fullDirname(cliArguments.inputFilePath);
console.log(`Watching ${watchDir} for changes`);
const watcher = watch(watchDir, {
recursive: true,
});
for await (const event of watcher) {
console.log(`Detected ${event.eventType} on ${event.filename}`);
lastProcessResult = await processBinding(cliArguments);
if (lastProcessResult === ExitCode.Error) {
console.error(`Error processing ${event.filename}`);
} else {
console.log("Reprocessed changes");
}
}
return ExitCode.Success;
}
return ExitCode.Success;
}
try {
const exitCode = await main();
process.exit(exitCode);