mirror of
https://github.com/wassname/talk.git
synced 2026-06-27 22:54:07 +08:00
2acc761a5d
* chore: upgrade eslint, typescript * chore: upgrade deps * chore: revert upgrade ts-node-dev * chore: revert unneeded comments Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import chalk from "chalk";
|
|
import spawn from "cross-spawn";
|
|
import { Cancelable, debounce } from "lodash";
|
|
|
|
import { Executor } from "./types";
|
|
|
|
interface CommandExecutorOptions {
|
|
args?: ReadonlyArray<string>;
|
|
/** If true, allow spawning multiple processes. */
|
|
spawnMutiple?: boolean;
|
|
|
|
/** Specify the period in which the process is started at max once. */
|
|
debounce?: number | false;
|
|
|
|
/** If true, will run command upon initialization. */
|
|
runOnInit?: boolean;
|
|
}
|
|
|
|
export default class CommandExecutor implements Executor {
|
|
private cmd: string;
|
|
private args?: ReadonlyArray<string>;
|
|
private spawnMultiple: boolean;
|
|
private runOnInit: boolean;
|
|
private isRunning = false;
|
|
private shouldRespawn = false;
|
|
private spawnProcessDebounced?: (() => void) & Cancelable;
|
|
|
|
constructor(cmd: string, opts: CommandExecutorOptions = {}) {
|
|
this.cmd = cmd;
|
|
this.args = opts.args;
|
|
this.spawnMultiple = opts.spawnMutiple || false;
|
|
this.runOnInit = opts.runOnInit || false;
|
|
|
|
const wait = opts.debounce === undefined ? 500 : opts.debounce;
|
|
if (wait) {
|
|
this.spawnProcessDebounced = debounce(() => this.spawnProcess(), wait);
|
|
}
|
|
}
|
|
|
|
// This is called before watching starts.
|
|
public onInit(): void {
|
|
if (this.runOnInit) {
|
|
this.spawnProcessPotentiallyDebounced();
|
|
}
|
|
}
|
|
|
|
private spawnProcessPotentiallyDebounced() {
|
|
if (this.spawnProcessDebounced) {
|
|
this.spawnProcessDebounced();
|
|
return;
|
|
}
|
|
this.spawnProcess();
|
|
}
|
|
|
|
private spawnProcess() {
|
|
if (this.isRunning && !this.spawnMultiple) {
|
|
this.shouldRespawn = true;
|
|
return;
|
|
}
|
|
this.isRunning = true;
|
|
this.shouldRespawn = false;
|
|
const child = spawn(this.cmd, this.args as string[], {
|
|
stdio: "inherit",
|
|
shell: !this.args,
|
|
});
|
|
|
|
child.on("close", (code: number) => {
|
|
this.isRunning = false;
|
|
if (code !== 0 && code !== null) {
|
|
// eslint-disable-next-line no-console
|
|
console.log(chalk.red(`Command exited with ${code}`));
|
|
}
|
|
if (this.shouldRespawn) {
|
|
this.spawnProcessPotentiallyDebounced();
|
|
}
|
|
});
|
|
}
|
|
|
|
public execute(filePath: string): void {
|
|
this.spawnProcessPotentiallyDebounced();
|
|
}
|
|
}
|