mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 13:17:24 +01:00
61 lines
1.6 KiB
JavaScript
61 lines
1.6 KiB
JavaScript
import { exec } from 'child_process';
|
|
import psTree from 'ps-tree';
|
|
import net from 'net';
|
|
import Q from 'q';
|
|
|
|
/*
|
|
* Kill a child process and any sub-children that process may have spawned.
|
|
* This is necessary to ensure that Gulp will terminate when it has completed
|
|
* its tasks.
|
|
*/
|
|
export function kill(proc) {
|
|
((pid) => {
|
|
psTree(pid, (_, pids) => {
|
|
if(pids.length) {
|
|
pids.forEach(kill); return
|
|
}
|
|
try {
|
|
exec(/^win/.test(process.platform)
|
|
? `taskkill /PID ${pid} /T /F`
|
|
: `kill -9 ${pid}`)
|
|
}
|
|
catch(e) { console.log(e) }
|
|
});
|
|
}(proc.PID || proc.pid));
|
|
};
|
|
|
|
/*
|
|
* Return a promise that will execute when Node is able to connect on a
|
|
* specific port. For example, this can be used to halt tasks until Selenium
|
|
* has fully spun up. Optionally provide a maximum number of seconds to wait
|
|
* before failing.
|
|
*/
|
|
export function awaitPort(port, max=60) {
|
|
let socket, timeout, interval;
|
|
let deferred = Q.defer();
|
|
|
|
timeout = setTimeout(() => {
|
|
clearInterval(interval);
|
|
deferred.reject(`Timed out after ${max} seconds`);
|
|
}, max * 1000);
|
|
|
|
interval = setInterval(() => {
|
|
socket = net.connect({port: port}, () => {
|
|
clearInterval(interval);
|
|
clearTimeout(timeout);
|
|
socket.destroy();
|
|
deferred.resolve();
|
|
}).on('error', () => { socket.destroy });
|
|
}, 1000);
|
|
|
|
return deferred.promise
|
|
};
|
|
|
|
/*
|
|
* Pipe the child's stdin and stderr to the parent process.
|
|
*/
|
|
export function pipe(child) {
|
|
child.stdout.on('data', (data) => { process.stdout.write(data) });
|
|
child.stderr.on('data', (data) => { process.stderr.write(data) });
|
|
};
|