@gnuechtel/shared-util 1.0.0-beta.2 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -8
- package/package.json +1 -1
- package/src/lib/create-process.d.ts +21 -1
- package/src/lib/create-process.js +73 -23
- package/src/lib/create-process.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
# shared-util
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Shared utility functions for [gnuechtel](https://www.npmjs.com/org/gnuechtel) projects
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Run `nx build shared-util` to build the library.
|
|
8
|
-
|
|
9
|
-
## Running unit tests
|
|
10
|
-
|
|
11
|
-
Run `nx test shared-util` to execute the unit tests via [Jest](https://jestjs.io).
|
|
5
|
+
May contain useful functions for other projects too, but is not optimized for them.
|
|
6
|
+
Semantic versioning is also not guaranteed here.
|
package/package.json
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { ChildProcess } from 'child_process';
|
|
3
|
+
type ProcessState = undefined | 'running' | 'ready' | 'stopping' | 'stopped';
|
|
4
|
+
export interface Process {
|
|
5
|
+
state: () => ProcessState;
|
|
6
|
+
stop: () => void;
|
|
7
|
+
}
|
|
8
|
+
export interface ProcessOptions {
|
|
9
|
+
cwd?: string;
|
|
10
|
+
useFork?: boolean;
|
|
11
|
+
background?: boolean;
|
|
12
|
+
readyWhen?: string;
|
|
13
|
+
silent?: boolean;
|
|
14
|
+
onStarted?: (childProcess: ChildProcess) => void;
|
|
15
|
+
onReady?: (readyMessage: string) => void;
|
|
16
|
+
onStopping?: (childProcessKilled: boolean) => void;
|
|
17
|
+
onStopped?: (childProcessKilled: boolean) => void;
|
|
18
|
+
name?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function createProcess(command: string, params: string[], processOptions?: ProcessOptions | undefined): Promise<Process>;
|
|
21
|
+
export {};
|
|
@@ -1,31 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createProcess = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const child_process_1 = require("child_process");
|
|
5
|
-
function createProcess(command,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
6
|
+
function createProcess(command, params, processOptions = undefined) {
|
|
7
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
let processState;
|
|
11
|
+
let childProcessKilled = false;
|
|
12
|
+
const isSilent = () => (processOptions === null || processOptions === void 0 ? void 0 : processOptions.silent) || processState === 'stopped'; // ignore output when process was stopped or silent is true
|
|
13
|
+
const nameOrCommand = (processOptions === null || processOptions === void 0 ? void 0 : processOptions.name) || command;
|
|
14
|
+
const options = { env: Object.assign({}, process.env), cwd: processOptions === null || processOptions === void 0 ? void 0 : processOptions.cwd };
|
|
15
|
+
const paramsAsString = params.join(' ');
|
|
16
|
+
const commandWithParams = command + (paramsAsString ? ` ${paramsAsString}` : '');
|
|
17
|
+
const childProcess = !(processOptions === null || processOptions === void 0 ? void 0 : processOptions.useFork)
|
|
18
|
+
? (0, child_process_1.exec)(commandWithParams, options)
|
|
19
|
+
: (0, child_process_1.fork)(command, params, Object.assign(Object.assign({}, options), { stdio: 'pipe' }));
|
|
20
|
+
processState = 'running';
|
|
21
|
+
if (processOptions === null || processOptions === void 0 ? void 0 : processOptions.onStarted)
|
|
22
|
+
processOptions.onStarted(childProcess);
|
|
23
|
+
function processInstance() {
|
|
24
|
+
return {
|
|
25
|
+
state: () => processState,
|
|
26
|
+
stop: () => {
|
|
27
|
+
if (processState === 'stopped')
|
|
28
|
+
return; // Already stopped
|
|
29
|
+
processState = 'stopping';
|
|
30
|
+
childProcessKilled = childProcess.kill();
|
|
31
|
+
if (processOptions === null || processOptions === void 0 ? void 0 : processOptions.onStopping)
|
|
32
|
+
processOptions.onStopping(childProcessKilled);
|
|
33
|
+
processState = 'stopped';
|
|
34
|
+
if (processOptions === null || processOptions === void 0 ? void 0 : processOptions.onStopped)
|
|
35
|
+
processOptions.onStopped(childProcessKilled);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
28
38
|
}
|
|
39
|
+
const processExitListener = () => childProcessKilled || childProcess.kill(); // Ensure the child process is killed when the parent exits
|
|
40
|
+
process.on('exit', processExitListener);
|
|
41
|
+
process.on('SIGTERM', processExitListener);
|
|
42
|
+
process.on('SIGINT', processExitListener);
|
|
43
|
+
process.on('SIGHUP', processExitListener);
|
|
44
|
+
(_a = childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
45
|
+
if (!isSilent())
|
|
46
|
+
process.stdout.write(data);
|
|
47
|
+
const dataAsString = data.toString();
|
|
48
|
+
if ((processOptions === null || processOptions === void 0 ? void 0 : processOptions.readyWhen) && dataAsString.includes(processOptions === null || processOptions === void 0 ? void 0 : processOptions.readyWhen)) {
|
|
49
|
+
processState = 'ready';
|
|
50
|
+
if (processOptions.onReady)
|
|
51
|
+
processOptions.onReady(dataAsString);
|
|
52
|
+
resolve(processInstance()); // Resolve when readyWhen matches (has no effect on background processes since it is already resolved)
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
(_b = childProcess === null || childProcess === void 0 ? void 0 : childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
56
|
+
if (!isSilent())
|
|
57
|
+
process.stderr.write(data);
|
|
58
|
+
});
|
|
59
|
+
const rejectConditionallyWithMessage = (err, exitCode = -1) => {
|
|
60
|
+
if (processState === 'stopped')
|
|
61
|
+
return; // do not reject when process is already stopped
|
|
62
|
+
if (exitCode === 0)
|
|
63
|
+
return; // do not reject when exit code is 0
|
|
64
|
+
if (!err) {
|
|
65
|
+
err = new Error(`Command failed: ${command}\nParameters: ${paramsAsString}\nExit code: ${exitCode}`);
|
|
66
|
+
}
|
|
67
|
+
const messagePart2 = exitCode ? `with exit code ${exitCode}` : `and an error occurred: ${err.message}`;
|
|
68
|
+
console.error(`${nameOrCommand} was ${processState} ${messagePart2}`);
|
|
69
|
+
reject(new Error(`Command failed: ${command}\nParameters: ${paramsAsString}\nExit code: ${exitCode}`));
|
|
70
|
+
};
|
|
71
|
+
childProcess.on('error', rejectConditionallyWithMessage);
|
|
72
|
+
childProcess.on('exit', (exitCode) => {
|
|
73
|
+
rejectConditionallyWithMessage(undefined, exitCode); // reject only if exit code is not zero
|
|
74
|
+
resolve(processInstance()); // finally we resolve here, when no background process was started or readyWhen did not match
|
|
75
|
+
});
|
|
76
|
+
// Resolve immediately on background process (after all listeners are registered)
|
|
77
|
+
if (processOptions === null || processOptions === void 0 ? void 0 : processOptions.background)
|
|
78
|
+
resolve(processInstance());
|
|
29
79
|
});
|
|
30
80
|
});
|
|
31
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-process.js","sourceRoot":"","sources":["../../../../../libs/shared-util/src/lib/create-process.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-process.js","sourceRoot":"","sources":["../../../../../libs/shared-util/src/lib/create-process.ts"],"names":[],"mappings":";;;;AAAA,iDAAyD;AAsBzD,SAAsB,aAAa,CACjC,OAAe,EACf,MAAgB,EAChB,iBAA6C,SAAS;;QAEtD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;YACrC,IAAI,YAA0B,CAAC;YAC/B,IAAI,kBAAkB,GAAG,KAAK,CAAC;YAE/B,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,MAAM,KAAI,YAAY,KAAK,SAAS,CAAC,CAAC,2DAA2D;YAExI,MAAM,aAAa,GAAG,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,IAAI,KAAI,OAAO,CAAC;YACtD,MAAM,OAAO,GAAG,EAAE,GAAG,oBAAO,OAAO,CAAC,GAAG,CAAE,EAAE,GAAG,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,GAAG,EAAE,CAAC;YACtE,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,iBAAiB,GAAG,OAAO,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACjF,MAAM,YAAY,GAAG,CAAC,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,OAAO,CAAA;gBAC3C,CAAC,CAAC,IAAA,oBAAI,EAAC,iBAAiB,EAAE,OAAO,CAAC;gBAClC,CAAC,CAAC,IAAA,oBAAI,EAAC,OAAO,EAAE,MAAM,kCAAO,OAAO,KAAE,KAAK,EAAE,MAAM,IAAG,CAAC;YACzD,YAAY,GAAG,SAAS,CAAC;YACzB,IAAI,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,SAAS;gBAAE,cAAc,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAEtE,SAAS,eAAe;gBACtB,OAAO;oBACL,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY;oBACzB,IAAI,EAAE,GAAG,EAAE;wBACT,IAAI,YAAY,KAAK,SAAS;4BAAE,OAAO,CAAC,kBAAkB;wBAC1D,YAAY,GAAG,UAAU,CAAC;wBAC1B,kBAAkB,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;wBACzC,IAAI,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU;4BAAE,cAAc,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;wBAC9E,YAAY,GAAG,SAAS,CAAC;wBACzB,IAAI,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,SAAS;4BAAE,cAAc,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;oBAC9E,CAAC;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,mBAAmB,GAAG,GAAG,EAAE,CAAC,kBAAkB,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,2DAA2D;YACxI,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;YACxC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;YAC3C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YAC1C,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YAE1C,MAAA,YAAY,CAAC,MAAM,0CAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACvC,IAAI,CAAC,QAAQ,EAAE;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrC,IAAI,CAAA,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,SAAS,KAAI,YAAY,CAAC,QAAQ,CAAC,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,SAAS,CAAC,EAAE;oBACjF,YAAY,GAAG,OAAO,CAAC;oBACvB,IAAI,cAAc,CAAC,OAAO;wBAAE,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;oBACjE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,sGAAsG;iBACnI;YACH,CAAC,CAAC,CAAC;YACH,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,0CAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxC,IAAI,CAAC,QAAQ,EAAE;oBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;YAEH,MAAM,8BAA8B,GAAG,CAAC,GAAW,EAAE,WAA0B,CAAC,CAAC,EAAE,EAAE;gBACnF,IAAI,YAAY,KAAK,SAAS;oBAAE,OAAO,CAAC,gDAAgD;gBACxF,IAAI,QAAQ,KAAK,CAAC;oBAAE,OAAO,CAAC,oCAAoC;gBAChE,IAAI,CAAC,GAAG,EAAE;oBACR,GAAG,GAAG,IAAI,KAAK,CAAC,mBAAmB,OAAO,qBAAqB,cAAc,qBAAqB,QAAQ,EAAE,CAAC,CAAC;iBAC/G;gBACD,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,kBAAkB,QAAQ,EAAE,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC;gBACvG,OAAO,CAAC,KAAK,CAAC,GAAG,aAAa,QAAQ,YAAY,IAAI,YAAY,EAAE,CAAC,CAAC;gBACtE,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,OAAO,qBAAqB,cAAc,qBAAqB,QAAQ,EAAE,CAAC,CAAC,CAAC;YAClH,CAAC,CAAC;YAEF,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;YACzD,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACnC,8BAA8B,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,uCAAuC;gBAC5F,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,6FAA6F;YAC3H,CAAC,CAAC,CAAC;YAEH,iFAAiF;YACjF,IAAI,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,UAAU;gBAAE,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC;CAAA;AA1ED,sCA0EC"}
|