UNPKG

typescript-assistant

Version:

Combines and integrates professional Typescript tools into your project

111 lines (96 loc) 2.86 kB
import { spawn } from "child_process"; import * as path from "path"; import { createInterface } from "readline"; import * as kill from "tree-kill"; import { Logger } from "./logger"; export interface Task { result: Promise<void>; kill(): void; } export interface TaskConfig { name: string; logger: Logger; handleOutput?(line: string): boolean; handleError?(line: string): boolean; } /** * Used for differences between windows and linux and it can also be mocked for unit tests */ export interface TaskRunner { runTask(command: string, args: string[], config: TaskConfig): Task; } let strip = (line: string) => /^\s*(.*?)\s*$/m.exec(line)![1]; export let createDefaultTaskRunner = (): TaskRunner => { return { runTask: (command: string, args: string[], config: TaskConfig) => { let loggerCategory = config.name; let logger = config.logger; let readableCommand = command .replace(`.${path.sep}node_modules${path.sep}.bin${path.sep}`, "") .replace(".cmd", ""); logger.log( loggerCategory, `running command ${readableCommand} ${args.join(" ")}` ); let task = spawn(command, args); let stdout = createInterface({ input: task.stdout }); stdout.on("line", (line) => { line = strip(line); if (!line) { return; } let handled = false; if (config.handleOutput) { handled = config.handleOutput(line); } if (!handled) { logger.log(loggerCategory, line); } }); let stderr = createInterface({ input: task.stderr }); stderr.on("line", (line) => { line = strip(line); if (!line) { return; } let handled = false; if (config.handleError) { handled = config.handleError(line); } if (!handled) { logger.error(loggerCategory, line); } }); let result = new Promise<void>((resolve, reject) => { task.on("close", (code: number) => { if (code === 0 || code === null) { resolve(); } else { reject(`Process exited with code ${code}`); } }); }); return { result, kill: () => { kill(task.pid!); }, }; }, }; }; export let createWindowsTaskRunner = (): TaskRunner => { let delegate = createDefaultTaskRunner(); let translateToWindows = (command: string) => { if (command.charAt(0) === ".") { // we just assume it is something from the ./node_modules/.bin/ folder command += ".cmd"; } return command.replace(/\//g, "\\"); }; return { runTask: (command: string, args: string[], config: TaskConfig) => { return delegate.runTask(translateToWindows(command), args, config); }, }; };