#!/usr/bin/env ts-node /* tslint:disable:no-shadowed-variable arrow-return-shorthand */ import cpm from "child_process"; import EventEmitter from "events"; import fsm from "fs"; import pathm from "path"; import utilm from "util"; import Consola from "consola"; const consola = Consola.create({throttle: -1, stdout: process.stderr}); import globby from "globby"; import jfp from "json-file-plus"; import yargs from "yargs"; const pexec = utilm.promisify(cpm.exec); const pexecFile = utilm.promisify(cpm.execFile); const preadFile = utilm.promisify(fsm.readFile); function waitFor(options: {event: string}, eventEmitter: EventEmitter): Promise { const { event } = options; return new Promise((resolve, reject) => { eventEmitter.on(event, (...args: any[]) => { resolve(args as ReturnType); }); }); } interface IPSpawnOptions extends cpm.SpawnOptions { raiseOnError?: boolean; capture?: { stderr?: boolean; stdout?: boolean; all?: boolean; }; } interface IPspawnReturn { code: number | null; signal: string | null; stderr?: string; stdout?: string; } function pspawn(args: string[], options?: IPSpawnOptions): Promise { consola.info(`${args.join(" ")}`); const capout = ( options && options.capture && ( options.capture.stdout || options.capture.all ) ); const caperr = ( options && options.capture && ( options.capture.stderr || options.capture.all ) ); if ( caperr || capout ) { options = { ...options, stdio: [ "inherit", capout ? "pipe" : "inherit", caperr ? "pipe" : "inherit" ] }; } const cp = cpm.spawn(args[0], args.slice(1), options); let stdout = undefined as string | undefined; let stderr = undefined as string | undefined; if ( capout ) { cp.stdout.on("data", (data) => { stdout = ( stdout || "" ) + data; }); } if ( caperr ) { cp.stderr.on("data", (data) => { stderr = ( stderr || "" ) + data; }); } return waitFor<[number | null, string | null]>({event: "close"}, cp) .then((rstatus) => { const [ code, signal ] = rstatus; if ( (!options || options.raiseOnError !== false) && code !== 0 ) { throw Error(`${args.join(" ")} : failed with code=${code} and signal=${signal}`); } else { const rval: IPspawnReturn = { code, signal }; if ( stdout ) { rval.stdout = stdout; } if ( stderr ) { rval.stderr = stderr; } return rval; } }); } function ospawn(args: string[], options?: IPSpawnOptions) { return pspawn(args, { stdio: "inherit", ...options}); } export async function main() { const parser = yargs .strict() .help("h") .alias("help", "h") .option("verbose", {alias: "v", describe: "increase verbosity", count: true, default: 0}) .command("run ", "", (yargs) => { return yargs; }) ; const parsed = parser.argv; (consola as any).level += parsed.verbose; consola.debug(`${__filename}: entry ...`); consola.debug(`parsed = `, parsed); const cpath = parsed._.join("/"); consola.debug(`cpath = `, cpath); if ( cpath === "run" ) { if ( parsed.command === "lint" ) { await ospawn(["tslint", "--project", "."]); } else if ( parsed.command === "lint:fix" ) { await ospawn(["tslint", "--project", ".", "--fix"]); } else if ( parsed.command === "build" ) { await ospawn(["tslint", "--project", "."]); await ospawn(["rimraf", "dist-cjs"]); await ospawn(["tsc"]); await ospawn(["copyfiles", "src/**/*.js", "--up", "1", "dist-cjs"]); } else if ( parsed.command === "build:fast" ) { await ospawn(["tsc"]); await ospawn(["copyfiles", "src/**/*.js", "--up", "1", "dist-cjs"]); } else if ( parsed.command === "clean" ) { await ospawn(["rimraf", "--glob", "dist-*/", "docs/", "*.tgz"]); } else if ( parsed.command === "distclean" ) { await ospawn(["rimraf", "--glob", "dist-*/", "docs/", "*.tgz"]); await ospawn(["rimraf", "--glob", "node_modules"]); } else if ( parsed.command === "tsc" ) { await ospawn(["tsc"]); } else if ( parsed.command === "tsc:w" ) { await ospawn(["tsc", "-w"]); } else if ( parsed.command === "fix:url" ) { const { stdout } = await ospawn(["git", "remote", "get-url", "origin"], { capture: { stdout: true } }); const remote = ( stdout || "" ).trim(); consola.info(`remote = ${remote}`); const pjpath = pathm.join(__dirname, "..", "package.json"); const jsonFile = await jfp(pjpath); jsonFile.set({repository: {url: remote}}); await jsonFile.save(); } else if ( parsed.command === "ftsf" ) { const files = await globby(["**/*.ts", "!node_modules"]); consola.debug(`files = ${files}`); await ospawn(["ls", "-ld", ...files]); } else { throw Error(`Unhnalded command ${parsed.command}`); } } else { throw Error(`Unhnalded command ${parsed.cpath}`); } } main().catch((error) => { consola.error(`error = `, error); process.exitCode = 1; });