1 | const { spawn } = require("child_process");
|
2 | const waitPort = require("wait-port");
|
3 | const isPortFree = require("is-port-free");
|
4 | const findFreePorts = require("find-free-ports");
|
5 | const { info } = require("simple-output");
|
6 | const { promisifyProcess } = require("./utils/process");
|
7 | const { completeHandler, errorHandler } = require("./utils/handlers");
|
8 |
|
9 | async function getOptions() {
|
10 | let command1, command2;
|
11 | const program = require("commander")
|
12 | .arguments("<cmd1> <cmd2>")
|
13 | .option("-p, --port <port>", "process port")
|
14 | .option("-t, --timeout <timeout>", "process timeout")
|
15 | .action((cmd1, cmd2) => ((command1 = cmd1), (command2 = cmd2)))
|
16 | .parse(process.argv);
|
17 |
|
18 | const host = "localhost";
|
19 | const port = parseInt(program.port) || (await findFreePorts())[0];
|
20 |
|
21 | return { host, port, command1, command2 };
|
22 | }
|
23 |
|
24 | function startProcess(command) {
|
25 | info(`Start npm process - ${command}...`);
|
26 |
|
27 | const process = spawn("npm", ["run", command], { stdio: "inherit" });
|
28 | process.on("exit", () => process.kill());
|
29 |
|
30 | return promisifyProcess(process);
|
31 | }
|
32 |
|
33 | function connectToPort(options) {
|
34 | const waitPortPromise = waitPort(options).catch(e => {
|
35 | console.log(e);
|
36 | throw new Error("First process didn't start in time");
|
37 | });
|
38 | console.log("\n");
|
39 |
|
40 | return waitPortPromise;
|
41 | }
|
42 |
|
43 | (async function main() {
|
44 | const options = await getOptions();
|
45 |
|
46 | await isPortFree(options.port).catch(() => {
|
47 | throw new Error(`Port ${options.port} is already in use`);
|
48 | });
|
49 |
|
50 | const processPromise = startProcess(options.command1);
|
51 |
|
52 | await connectToPort(options);
|
53 | await Promise.race([processPromise, startProcess(options.command2)]);
|
54 |
|
55 | completeHandler();
|
56 | })().catch(errorHandler);
|