You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			98 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			98 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
| import { ChildProcessWithoutNullStreams, spawn } from "child_process";
 | |
| import Emittery from "emittery";
 | |
| 
 | |
| export default function simpleSpawn(
 | |
|   cmd: string,
 | |
|   arg: string[]
 | |
| ): Promise<{ stdout: string; stderr: string }> {
 | |
|   const process = spawn(cmd, arg);
 | |
|   let output = "";
 | |
|   let err = "";
 | |
|   return new Promise((resolve, reject) => {
 | |
|     process.on("close", (code) => {
 | |
|       code === 0 ? resolve({ stdout: output, stderr: err }) : reject(err);
 | |
|     });
 | |
|     process.stdout.on("data", (data) => (output += data.toString("utf-8")));
 | |
|     process.stderr.on("data", (data) => (err += data.toString("utf-8")));
 | |
|   });
 | |
| }
 | |
| 
 | |
| export class DeferedSpawn extends Emittery {
 | |
|   constructor(private process: ChildProcessWithoutNullStreams) {
 | |
|     super();
 | |
|     this.on("data", (data) => console.log("data", data.toString()));
 | |
|   }
 | |
| 
 | |
|   async waitForAnswer(): Promise<string> {
 | |
|     return new Promise((resolve, reject) => {
 | |
|       this.on("success", (data) => {
 | |
|         resolve(data);
 | |
|       });
 | |
|       this.on("error", reject);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async waitForNextData(): Promise<string | null> {
 | |
|     console.log(
 | |
|       "waiting for next data from",,
 | |
|       this.process.spawnargs.join(" ")
 | |
|     );
 | |
|     return new Promise((resolve, reject) => {
 | |
|       this.on("data", (data) => {
 | |
|         console.log("got answer from process", this.process.spawnfile);
 | |
|         resolve(data.toString("utf-8"));
 | |
|       });
 | |
|       this.on("error", (err) => {
 | |
|         console.error("Rejecting from process", this.process.spawnfile, err);
 | |
|         reject(err);
 | |
|       });
 | |
|       this.on("end", () => resolve(null));
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   kill() {
 | |
|     console.log("killing process!", this.process.spawnargs.join(" "));
 | |
|     process.kill(-this.process.pid); // https://stackoverflow.com/a/49842576
 | |
|   }
 | |
| 
 | |
|   write(data: string) {
 | |
|     this.process.stdin.write(data);
 | |
|   }
 | |
| }
 | |
| 
 | |
| export function deferedSpawn(
 | |
|   cmd: string,
 | |
|   arg: string[]
 | |
| ): Promise<DeferedSpawn> {
 | |
|   const process = spawn(cmd, arg, { detached: true });
 | |
|   let spawned = false;
 | |
|   let output = "";
 | |
|   let err = "";
 | |
|   const emitter = new DeferedSpawn(process);
 | |
|   return new Promise((resolve, reject) => {
 | |
|     process.stdout.on("data", (data) => {
 | |
|       output += data.toString("utf-8");
 | |
|       emitter.emit("data", data);
 | |
|     });
 | |
|     process.stderr.on("data", (data) => {
 | |
|       err += data.toString("utf-8");
 | |
|     });
 | |
|     process.on("spawn", () => {
 | |
|       resolve(emitter);
 | |
|     });
 | |
|     process.on("close", (code) => {
 | |
|       if (!spawned) {
 | |
|         reject(err);
 | |
|       } else {
 | |
|         console.log("!!!!!!!!!!!!!!!!!!!! PROCESS CLOSED");
 | |
|         if (code === 0) {
 | |
|           emitter.emit("success", output);
 | |
|         } else {
 | |
|           emitter.emit("error", err);
 | |
|         }
 | |
|         emitter.emit("end", { err, output });
 | |
|       }
 | |
|     });
 | |
|   });
 | |
| }
 |