teen_process 2.1.6 → 2.1.8
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/build/index.js +18 -0
- package/build/lib/circular-buffer.d.ts +13 -0
- package/build/lib/circular-buffer.d.ts.map +1 -0
- package/build/lib/circular-buffer.js +54 -0
- package/build/lib/circular-buffer.js.map +1 -0
- package/build/lib/exec.d.ts +5 -5
- package/build/lib/exec.d.ts.map +1 -1
- package/build/lib/exec.js +20 -40
- package/build/lib/exec.js.map +1 -1
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +1 -2
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/index.d.ts +0 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/subprocess.d.ts +9 -12
- package/build/lib/subprocess.d.ts.map +1 -1
- package/build/lib/subprocess.js +28 -59
- package/build/lib/subprocess.js.map +1 -1
- package/index.js +1 -1
- package/lib/circular-buffer.ts +60 -0
- package/lib/exec.js +20 -38
- package/lib/subprocess.js +29 -69
- package/package.json +5 -7
package/build/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./lib/index"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const MAX_BUFFER_SIZE: number;
|
|
2
|
+
export declare class CircularBuffer {
|
|
3
|
+
private _buf;
|
|
4
|
+
private _size;
|
|
5
|
+
private _maxSize;
|
|
6
|
+
constructor(maxSize?: number);
|
|
7
|
+
get size(): number;
|
|
8
|
+
get count(): number;
|
|
9
|
+
add(item: Buffer): this;
|
|
10
|
+
value(): Buffer;
|
|
11
|
+
private _align;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=circular-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circular-buffer.d.ts","sourceRoot":"","sources":["../../lib/circular-buffer.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,QAAoB,CAAC;AAGjD,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,SAAkB;IAMrC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAEM,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOvB,KAAK,IAAI,MAAM;IAItB,OAAO,CAAC,MAAM;CA0Bf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircularBuffer = exports.MAX_BUFFER_SIZE = void 0;
|
|
4
|
+
exports.MAX_BUFFER_SIZE = 100 * 1024 * 1024; // 100 MiB
|
|
5
|
+
const THRESHOLD = 0.15;
|
|
6
|
+
class CircularBuffer {
|
|
7
|
+
constructor(maxSize = exports.MAX_BUFFER_SIZE) {
|
|
8
|
+
this._maxSize = maxSize;
|
|
9
|
+
this._buf = [];
|
|
10
|
+
this._size = 0;
|
|
11
|
+
}
|
|
12
|
+
get size() {
|
|
13
|
+
return this._size;
|
|
14
|
+
}
|
|
15
|
+
get count() {
|
|
16
|
+
return this._buf.length;
|
|
17
|
+
}
|
|
18
|
+
add(item) {
|
|
19
|
+
this._buf.push(item);
|
|
20
|
+
this._size += item.length;
|
|
21
|
+
this._align();
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
value() {
|
|
25
|
+
return Buffer.concat(this._buf);
|
|
26
|
+
}
|
|
27
|
+
_align() {
|
|
28
|
+
if (this._size <= this._maxSize) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let numberOfItemsToShift = 0;
|
|
32
|
+
// We add the threshold to avoid shifting the array for each `add` call,
|
|
33
|
+
// which reduces the CPU usage
|
|
34
|
+
const expectedSizeToShift = this._size - this._maxSize + Math.trunc(this._maxSize * THRESHOLD);
|
|
35
|
+
let actualShiftedSize = 0;
|
|
36
|
+
while (numberOfItemsToShift < this._buf.length - 1 && actualShiftedSize <= expectedSizeToShift) {
|
|
37
|
+
actualShiftedSize += this._buf[numberOfItemsToShift].length;
|
|
38
|
+
numberOfItemsToShift++;
|
|
39
|
+
}
|
|
40
|
+
if (numberOfItemsToShift > 0) {
|
|
41
|
+
this._buf.splice(0, numberOfItemsToShift);
|
|
42
|
+
this._size -= actualShiftedSize;
|
|
43
|
+
}
|
|
44
|
+
if (actualShiftedSize < expectedSizeToShift) {
|
|
45
|
+
// We have already deleted all buffer items, but one,
|
|
46
|
+
// although the recent item is still too big to fit into the allowed size limit
|
|
47
|
+
const remainderToShift = expectedSizeToShift - actualShiftedSize;
|
|
48
|
+
this._buf[0] = this._buf[0].subarray(remainderToShift);
|
|
49
|
+
this._size -= remainderToShift;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.CircularBuffer = CircularBuffer;
|
|
54
|
+
//# sourceMappingURL=circular-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circular-buffer.js","sourceRoot":"","sources":["../../lib/circular-buffer.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,UAAU;AAC5D,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB,MAAa,cAAc;IAKzB,YAAY,OAAO,GAAG,uBAAe;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAEM,GAAG,CAAC,IAAY;QACrB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,KAAK;QACV,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEO,MAAM;QACZ,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,oBAAoB,GAAG,CAAC,CAAC;QAC7B,wEAAwE;QACxE,8BAA8B;QAC9B,MAAM,mBAAmB,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;QAC/F,IAAI,iBAAiB,GAAG,CAAC,CAAC;QAC1B,OAAO,oBAAoB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,IAAI,mBAAmB,EAAE,CAAC;YAC/F,iBAAiB,IAAI,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC;YAC5D,oBAAoB,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,oBAAoB,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC;QAClC,CAAC;QACD,IAAI,iBAAiB,GAAG,mBAAmB,EAAE,CAAC;YAC5C,qDAAqD;YACrD,+EAA+E;YAC/E,MAAM,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;YACvD,IAAI,CAAC,KAAK,IAAI,gBAAgB,CAAC;QACjC,CAAC;IACH,CAAC;CACF;AAxDD,wCAwDC"}
|
package/build/lib/exec.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export type TeenProcessLogger = {
|
|
|
37
37
|
/**
|
|
38
38
|
* Options for {@link exec teen_process.exec}.
|
|
39
39
|
*/
|
|
40
|
-
export type TeenProcessExecOptions = import(
|
|
40
|
+
export type TeenProcessExecOptions = import("child_process").SpawnOptions & TeenProcessProps;
|
|
41
41
|
/**
|
|
42
42
|
* The value {@link exec teen_process.exec} resolves to when `isBuffer` is `false`
|
|
43
43
|
*/
|
|
@@ -94,15 +94,15 @@ export type TeenProcessExecErrorProps = {
|
|
|
94
94
|
*/
|
|
95
95
|
export type TeenProcessExecError = Error & TeenProcessExecErrorProps;
|
|
96
96
|
export type BufferProp<MaybeBuffer extends {
|
|
97
|
-
isBuffer?: boolean
|
|
98
|
-
}> = MaybeBuffer[
|
|
97
|
+
isBuffer?: boolean;
|
|
98
|
+
}> = MaybeBuffer["isBuffer"];
|
|
99
99
|
/**
|
|
100
100
|
* Spawns a process
|
|
101
101
|
* @template {TeenProcessExecOptions} T
|
|
102
102
|
* @param {string} cmd - Program to execute
|
|
103
103
|
* @param {string[]} [args] - Arguments to pass to the program
|
|
104
|
-
* @param {T} [
|
|
104
|
+
* @param {T} [originalOpts] - Options
|
|
105
105
|
* @returns {Promise<BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult>}
|
|
106
106
|
*/
|
|
107
|
-
export function exec<T extends TeenProcessExecOptions>(cmd: string, args?: string[] | undefined,
|
|
107
|
+
export function exec<T extends TeenProcessExecOptions>(cmd: string, args?: string[] | undefined, originalOpts?: T | undefined): Promise<BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult>;
|
|
108
108
|
//# sourceMappingURL=exec.d.ts.map
|
package/build/lib/exec.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../lib/exec.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../lib/exec.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAqJc,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI;;;;;qCAKzB,OAAO,eAAe,EAAE,YAAY,GAAG,gBAAgB;;;;;;;;YAMtD,MAAM;;;;YACN,MAAM;;;;UACN,MAAM,OAAC;;;;;;;;;YAMP,MAAM;;;;YACN,MAAM;;;;UACN,MAAM,OAAC;;;;;;;;;YAMP,MAAM;;;;YACN,MAAM;;;;UACN,MAAM,OAAC;;;;;mCAKR,KAAK,GAAG,yBAAyB;uBAIV,WAAW,SAAlC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,IACtB,WAAW,CAAC,UAAU,CAAC;AArLpC;;;;;;;GAOG;AACH,qBANsC,CAAC,SAAzB,sBAAuB,OAC1B,MAAM,8DAGJ,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,2BAA2B,GAAG,2BAA2B,CAAC,CAqH3G"}
|
package/build/lib/exec.js
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable promise/prefer-await-to-callbacks */
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
6
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.exec =
|
|
6
|
+
exports.exec = exec;
|
|
8
7
|
const child_process_1 = require("child_process");
|
|
9
8
|
const shell_quote_1 = require("shell-quote");
|
|
10
9
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
11
10
|
const lodash_1 = __importDefault(require("lodash"));
|
|
12
11
|
const helpers_1 = require("./helpers");
|
|
13
|
-
const
|
|
12
|
+
const circular_buffer_1 = require("./circular-buffer");
|
|
14
13
|
/**
|
|
15
14
|
* Spawns a process
|
|
16
15
|
* @template {TeenProcessExecOptions} T
|
|
17
16
|
* @param {string} cmd - Program to execute
|
|
18
17
|
* @param {string[]} [args] - Arguments to pass to the program
|
|
19
|
-
* @param {T} [
|
|
18
|
+
* @param {T} [originalOpts] - Options
|
|
20
19
|
* @returns {Promise<BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult>}
|
|
21
20
|
*/
|
|
22
|
-
async function exec(cmd, args = [],
|
|
21
|
+
async function exec(cmd, args = [], originalOpts = /** @type {T} */ ({})) {
|
|
23
22
|
// get a quoted representation of the command for error strings
|
|
24
23
|
const rep = (0, shell_quote_1.quote)([cmd, ...args]);
|
|
25
24
|
// extend default options; we're basically re-implementing exec's options
|
|
26
25
|
// for use here with spawn under the hood
|
|
27
|
-
opts = /** @type {T} */ (lodash_1.default.defaults(
|
|
26
|
+
const opts = /** @type {T} */ (lodash_1.default.defaults(originalOpts, {
|
|
28
27
|
timeout: null,
|
|
29
28
|
encoding: 'utf8',
|
|
30
29
|
killSignal: 'SIGTERM',
|
|
@@ -35,16 +34,18 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
35
34
|
isBuffer: false,
|
|
36
35
|
shell: undefined,
|
|
37
36
|
logger: undefined,
|
|
38
|
-
maxStdoutBufferSize: MAX_BUFFER_SIZE,
|
|
39
|
-
maxStderrBufferSize: MAX_BUFFER_SIZE,
|
|
37
|
+
maxStdoutBufferSize: circular_buffer_1.MAX_BUFFER_SIZE,
|
|
38
|
+
maxStderrBufferSize: circular_buffer_1.MAX_BUFFER_SIZE,
|
|
40
39
|
}));
|
|
41
40
|
const isBuffer = Boolean(opts.isBuffer);
|
|
42
41
|
// this is an async function, so return a promise
|
|
43
42
|
return await new bluebird_1.default((resolve, reject) => {
|
|
44
43
|
// spawn the child process with options; we don't currently expose any of
|
|
45
44
|
// the other 'spawn' options through the API
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const proc = (0, child_process_1.spawn)(cmd, args, { cwd: opts.cwd, env: opts.env, shell: opts.shell });
|
|
46
|
+
const stdoutBuffer = new circular_buffer_1.CircularBuffer(opts.maxStdoutBufferSize);
|
|
47
|
+
const stderrBuffer = new circular_buffer_1.CircularBuffer(opts.maxStderrBufferSize);
|
|
48
|
+
let timer = null;
|
|
48
49
|
// if the process errors out, reject the promise
|
|
49
50
|
proc.on('error', /** @param {NodeJS.ErrnoException} err */ async (err) => {
|
|
50
51
|
if (err.code === 'ENOENT') {
|
|
@@ -57,7 +58,7 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
57
58
|
reject(new Error(`Standard input '${err.syscall}' error: ${err.stack}`));
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
|
-
const handleStream = (streamType,
|
|
61
|
+
const handleStream = (/** @type {string} */ streamType, /** @type {CircularBuffer} */ buffer) => {
|
|
61
62
|
if (!proc[streamType]) {
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
@@ -70,43 +71,23 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
70
71
|
return;
|
|
71
72
|
}
|
|
72
73
|
// keep track of the stream if we don't want to ignore it
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
proc[streamType].on('data', (chunk) => {
|
|
76
|
-
chunks.push(chunk);
|
|
77
|
-
size += chunk.length;
|
|
78
|
-
while (chunks.length > 1 && size >= maxSize) {
|
|
79
|
-
size -= chunks[0].length;
|
|
80
|
-
chunks.shift();
|
|
81
|
-
}
|
|
74
|
+
proc[streamType].on('data', (/** @type {Buffer} */ chunk) => {
|
|
75
|
+
buffer.add(chunk);
|
|
82
76
|
if (opts.logger && lodash_1.default.isFunction(opts.logger.debug)) {
|
|
83
77
|
opts.logger.debug(chunk.toString());
|
|
84
78
|
}
|
|
85
79
|
});
|
|
86
80
|
};
|
|
87
|
-
handleStream('stdout',
|
|
88
|
-
|
|
89
|
-
chunks: stdoutArr,
|
|
90
|
-
});
|
|
91
|
-
handleStream('stderr', {
|
|
92
|
-
maxSize: opts.maxStderrBufferSize,
|
|
93
|
-
chunks: stderrArr,
|
|
94
|
-
});
|
|
81
|
+
handleStream('stdout', stdoutBuffer);
|
|
82
|
+
handleStream('stderr', stderrBuffer);
|
|
95
83
|
/**
|
|
96
84
|
* @template {boolean} U
|
|
97
85
|
* @param {U} isBuffer
|
|
98
86
|
* @returns {U extends true ? {stdout: Buffer, stderr: Buffer} : {stdout: string, stderr: string}}
|
|
99
87
|
*/
|
|
100
88
|
function getStdio(isBuffer) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
stdout = Buffer.concat(stdoutArr);
|
|
104
|
-
stderr = Buffer.concat(stderrArr);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
stdout = Buffer.concat(stdoutArr).toString(opts.encoding);
|
|
108
|
-
stderr = Buffer.concat(stderrArr).toString(opts.encoding);
|
|
109
|
-
}
|
|
89
|
+
const stdout = isBuffer ? stdoutBuffer.value() : stdoutBuffer.value().toString(opts.encoding);
|
|
90
|
+
const stderr = isBuffer ? stderrBuffer.value() : stderrBuffer.value().toString(opts.encoding);
|
|
110
91
|
return /** @type {U extends true ? {stdout: Buffer, stderr: Buffer} : {stdout: string, stderr: string}} */ ({ stdout, stderr });
|
|
111
92
|
}
|
|
112
93
|
// if the process ends, either resolve or reject the promise based on the
|
|
@@ -116,7 +97,7 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
116
97
|
if (timer) {
|
|
117
98
|
clearTimeout(timer);
|
|
118
99
|
}
|
|
119
|
-
|
|
100
|
+
const { stdout, stderr } = getStdio(isBuffer);
|
|
120
101
|
if (code === 0) {
|
|
121
102
|
resolve(/** @type {BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult} */ ({ stdout, stderr, code }));
|
|
122
103
|
}
|
|
@@ -131,7 +112,7 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
131
112
|
// have in case it's helpful in debugging
|
|
132
113
|
if (opts.timeout) {
|
|
133
114
|
timer = setTimeout(() => {
|
|
134
|
-
|
|
115
|
+
const { stdout, stderr } = getStdio(isBuffer);
|
|
135
116
|
let err = new Error(`Command '${rep}' timed out after ${opts.timeout}ms`);
|
|
136
117
|
err = Object.assign(err, { stdout, stderr, code: null });
|
|
137
118
|
reject(err);
|
|
@@ -142,7 +123,6 @@ async function exec(cmd, args = [], opts = /** @type {T} */ ({})) {
|
|
|
142
123
|
}
|
|
143
124
|
});
|
|
144
125
|
}
|
|
145
|
-
exports.exec = exec;
|
|
146
126
|
exports.default = exec;
|
|
147
127
|
/**
|
|
148
128
|
* Options on top of `SpawnOptions`, unique to `teen_process.`
|
package/build/lib/exec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../lib/exec.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../lib/exec.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../lib/helpers.js"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,oCAPW,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../lib/helpers.js"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,oCAPW,MAAM,CAAC,cAAc,OAErB,MAAM,oCAEJ,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAwB1C"}
|
package/build/lib/helpers.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatEnoent =
|
|
6
|
+
exports.formatEnoent = formatEnoent;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
9
|
/**
|
|
@@ -39,5 +39,4 @@ async function formatEnoent(error, cmd, cwd = null) {
|
|
|
39
39
|
`nor in any folders specified in the PATH environment variable (${pathMsg})`;
|
|
40
40
|
return error;
|
|
41
41
|
}
|
|
42
|
-
exports.formatEnoent = formatEnoent;
|
|
43
42
|
//# sourceMappingURL=helpers.js.map
|
package/build/lib/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../lib/helpers.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../lib/helpers.js"],"names":[],"mappings":";;;;;AAqCS,oCAAY;AArCrB,gDAAwB;AACxB,2DAA6B;AAE7B;;;;;;;;;;GAUG;AACH,KAAK,UAAU,YAAY,CAAE,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI;IACjD,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,OAAO,GAAG,0BAA0B,GAAG,SAAS,GAAG,8BAA8B,CAAC;gBACxF,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxB,KAAK,CAAC,OAAO,GAAG,0BAA0B,GAAG,SAAS,GAAG,kBAAkB,CAAC;gBAC5E,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,sCAAsC,CAAC;IAC3E,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,oEAAoE,MAAM,IAAI;QACnG,kEAAkE,OAAO,GAAG,CAAC;IAC/E,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/build/lib/index.d.ts
CHANGED
package/build/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.js"],"names":[],"mappings":";;;2BAK2B,QAAQ;oBAFf,eAAe;yBACV,cAAc"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
export default SubProcess;
|
|
3
2
|
export type StartDetector = (stdout: string, stderr?: string | undefined) => any;
|
|
4
3
|
export class SubProcess extends events<[never]> {
|
|
@@ -8,15 +7,8 @@ export class SubProcess extends events<[never]> {
|
|
|
8
7
|
* @param {any} [opts]
|
|
9
8
|
*/
|
|
10
9
|
constructor(cmd: string, args?: string[] | undefined, opts?: any);
|
|
11
|
-
/**
|
|
12
|
-
* @type { {stdout: string, stderr: string} }
|
|
13
|
-
*/
|
|
14
|
-
lastLinePortion: {
|
|
15
|
-
stdout: string;
|
|
16
|
-
stderr: string;
|
|
17
|
-
};
|
|
18
10
|
/** @type {import('child_process').ChildProcess?} */
|
|
19
|
-
proc: import(
|
|
11
|
+
proc: import("child_process").ChildProcess | null;
|
|
20
12
|
/** @type {string[]} */
|
|
21
13
|
args: string[];
|
|
22
14
|
/**
|
|
@@ -38,11 +30,13 @@ export class SubProcess extends events<[never]> {
|
|
|
38
30
|
get isRunning(): boolean;
|
|
39
31
|
/**
|
|
40
32
|
*
|
|
41
|
-
* @param {string}
|
|
42
|
-
* @param {Iterable<string
|
|
33
|
+
* @param {string} streamName
|
|
34
|
+
* @param {Iterable<string>|string} lines
|
|
43
35
|
*/
|
|
44
|
-
emitLines(
|
|
36
|
+
emitLines(streamName: string, lines: Iterable<string> | string): void;
|
|
45
37
|
/**
|
|
38
|
+
* spawn the subprocess and return control whenever we deem that it has fully
|
|
39
|
+
* "started"
|
|
46
40
|
*
|
|
47
41
|
* @param {StartDetector|number?} startDetector
|
|
48
42
|
* @param {number?} timeoutMs
|
|
@@ -50,6 +44,9 @@ export class SubProcess extends events<[never]> {
|
|
|
50
44
|
* @returns {Promise<void>}
|
|
51
45
|
*/
|
|
52
46
|
start(startDetector?: StartDetector | (number | null), timeoutMs?: number | null, detach?: boolean): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* @deprecated This method is deprecated and will be removed
|
|
49
|
+
*/
|
|
53
50
|
handleLastLines(): void;
|
|
54
51
|
/**
|
|
55
52
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subprocess.d.ts","sourceRoot":"","sources":["../../lib/subprocess.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subprocess.d.ts","sourceRoot":"","sources":["../../lib/subprocess.js"],"names":[],"mappings":";qCA8SW,MAAM,kCAEJ,GAAG;AAvShB;IA4BE;;;;OAIG;IACH,iBAJW,MAAM,sCAEN,GAAG,EAgBb;IA7CD,oDAAoD;IACpD,MADW,OAAO,eAAe,EAAE,YAAY,OAAC,CAC3C;IAEL,uBAAuB;IACvB,MADW,MAAM,EAAE,CACd;IAEL;;OAEG;IACH,KAFU,MAAM,CAEZ;IAEJ;;MAEE;IACF,MAFU,GAAG,CAER;IAEL;;OAEG;IACH,eAFU,OAAO,CAEH;IAEd;;OAEG;IACH,KAFU,MAAM,CAEZ;IAuBJ,yBAGC;IAED;;;;OAIG;IACH,sBAHW,MAAM,SACN,QAAQ,CAAC,MAAM,CAAC,GAAC,MAAM,QAYjC;IAED;;;;;;;;OAQG;IACH,sBALW,aAAa,IAAC,MAAM,OAAC,CAAA,cACrB,MAAM,OAAC,WACP,OAAO,GACL,OAAO,CAAC,IAAI,CAAC,CAgJzB;IAED;;OAEG;IACH,wBAGC;IAED;;;;;OAKG;IACH,cAJW,MAAM,CAAC,OAAO,YACd,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED,gDAcC;IAKD,sBAQC;IAED,qCAEC;CACF;mBAtSkB,QAAQ"}
|
package/build/lib/subprocess.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable promise/prefer-await-to-callbacks */
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -12,16 +11,7 @@ const bluebird_1 = __importDefault(require("bluebird"));
|
|
|
12
11
|
const shell_quote_1 = require("shell-quote");
|
|
13
12
|
const lodash_1 = __importDefault(require("lodash"));
|
|
14
13
|
const helpers_1 = require("./helpers");
|
|
15
|
-
|
|
16
|
-
// when the process output is too long and contains
|
|
17
|
-
// no line breaks
|
|
18
|
-
const MAX_LINE_PORTION_LENGTH = 0xFFFF;
|
|
19
|
-
function cutSuffix(str, suffixLength) {
|
|
20
|
-
return str.length > suffixLength
|
|
21
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
|
22
|
-
? ` ${str.substr(str.length - suffixLength)}`.substr(1)
|
|
23
|
-
: str;
|
|
24
|
-
}
|
|
14
|
+
const node_readline_1 = require("node:readline");
|
|
25
15
|
class SubProcess extends EventEmitter {
|
|
26
16
|
/**
|
|
27
17
|
* @param {string} cmd
|
|
@@ -43,7 +33,6 @@ class SubProcess extends EventEmitter {
|
|
|
43
33
|
this.expectingExit = false;
|
|
44
34
|
// get a quoted representation of the command for error strings
|
|
45
35
|
this.rep = (0, shell_quote_1.quote)([cmd, ...args]);
|
|
46
|
-
this.lastLinePortion = { stdout: '', stderr: '' };
|
|
47
36
|
}
|
|
48
37
|
get isRunning() {
|
|
49
38
|
// presence of `proc` means we have connected and started
|
|
@@ -51,17 +40,23 @@ class SubProcess extends EventEmitter {
|
|
|
51
40
|
}
|
|
52
41
|
/**
|
|
53
42
|
*
|
|
54
|
-
* @param {string}
|
|
55
|
-
* @param {Iterable<string
|
|
43
|
+
* @param {string} streamName
|
|
44
|
+
* @param {Iterable<string>|string} lines
|
|
56
45
|
*/
|
|
57
|
-
emitLines(
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
emitLines(streamName, lines) {
|
|
47
|
+
const doEmit = (/** @type {string} */ line) => this.emit('stream-line', `[${streamName.toUpperCase()}] ${line}`);
|
|
48
|
+
if (lodash_1.default.isString(lines)) {
|
|
49
|
+
doEmit(lines);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
for (const line of lines) {
|
|
53
|
+
doEmit(line);
|
|
54
|
+
}
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
|
-
// spawn the subprocess and return control whenever we deem that it has fully
|
|
63
|
-
// "started"
|
|
64
57
|
/**
|
|
58
|
+
* spawn the subprocess and return control whenever we deem that it has fully
|
|
59
|
+
* "started"
|
|
65
60
|
*
|
|
66
61
|
* @param {StartDetector|number?} startDetector
|
|
67
62
|
* @param {number?} timeoutMs
|
|
@@ -108,7 +103,6 @@ class SubProcess extends EventEmitter {
|
|
|
108
103
|
if (this.proc.stderr) {
|
|
109
104
|
this.proc.stderr.setEncoding(this.opts.encoding || 'utf8');
|
|
110
105
|
}
|
|
111
|
-
this.lastLinePortion = { stdout: '', stderr: '' };
|
|
112
106
|
// this function handles output that we collect from the subproc
|
|
113
107
|
/**
|
|
114
108
|
*
|
|
@@ -129,33 +123,6 @@ class SubProcess extends EventEmitter {
|
|
|
129
123
|
}
|
|
130
124
|
// emit the actual output for whomever's listening
|
|
131
125
|
this.emit('output', stdout, stderr);
|
|
132
|
-
// we also want to emit lines, but it's more complex since output
|
|
133
|
-
// comes in chunks and a line could come in two different chunks, so
|
|
134
|
-
// we have logic to handle that case (using this.lastLinePortion to
|
|
135
|
-
// remember a line that started but did not finish in the last chunk)
|
|
136
|
-
for (const [streamName, streamData] of /** @type {[['stdout', string], ['stderr', string]]} */ (lodash_1.default.toPairs(streams))) {
|
|
137
|
-
if (!streamData)
|
|
138
|
-
continue; // eslint-disable-line curly
|
|
139
|
-
const lines = streamData.split('\n')
|
|
140
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
|
141
|
-
.map((x) => ` ${x}`.substr(1));
|
|
142
|
-
if (lines.length > 1) {
|
|
143
|
-
lines[0] = this.lastLinePortion[streamName] + lines[0];
|
|
144
|
-
this.lastLinePortion[streamName] = cutSuffix(lodash_1.default.last(lines), MAX_LINE_PORTION_LENGTH);
|
|
145
|
-
const resultLines = lines.slice(0, -1);
|
|
146
|
-
this.emit(`lines-${streamName}`, resultLines);
|
|
147
|
-
this.emitLines(streamName, resultLines);
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
const currentPortion = cutSuffix(lines[0], MAX_LINE_PORTION_LENGTH);
|
|
151
|
-
if (this.lastLinePortion[streamName].length + currentPortion.length > MAX_LINE_PORTION_LENGTH) {
|
|
152
|
-
this.lastLinePortion[streamName] = currentPortion;
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
this.lastLinePortion[streamName] += currentPortion;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
126
|
};
|
|
160
127
|
// if we get an error spawning the proc, reject and clean up the proc
|
|
161
128
|
this.proc.on('error', /** @param {NodeJS.ErrnoException} err */ async (err) => {
|
|
@@ -168,17 +135,25 @@ class SubProcess extends EventEmitter {
|
|
|
168
135
|
this.proc?.unref();
|
|
169
136
|
this.proc = null;
|
|
170
137
|
});
|
|
138
|
+
const handleStreamLines = (/** @type {string} */ streamName, /** @type {import('stream').Readable} */ input) => {
|
|
139
|
+
const rl = (0, node_readline_1.createInterface)({ input });
|
|
140
|
+
rl.on('line', (line) => {
|
|
141
|
+
this.emit(`lines-${streamName}`, [line]);
|
|
142
|
+
this.emitLines(streamName, line);
|
|
143
|
+
});
|
|
144
|
+
};
|
|
171
145
|
if (this.proc.stdout) {
|
|
172
146
|
this.proc.stdout.on('data', (chunk) => handleOutput({ stdout: chunk.toString(), stderr: '' }));
|
|
147
|
+
handleStreamLines('stdout', this.proc.stdout);
|
|
173
148
|
}
|
|
174
149
|
if (this.proc.stderr) {
|
|
175
150
|
this.proc.stderr.on('data', (chunk) => handleOutput({ stdout: '', stderr: chunk.toString() }));
|
|
151
|
+
handleStreamLines('stderr', this.proc.stderr);
|
|
176
152
|
}
|
|
177
153
|
// when the proc exits, we might still have a buffer of lines we were
|
|
178
154
|
// waiting on more chunks to complete. Go ahead and emit those, then
|
|
179
155
|
// re-emit the exit so a listener can handle the possibly-unexpected exit
|
|
180
156
|
this.proc.on('exit', (code, signal) => {
|
|
181
|
-
this.handleLastLines();
|
|
182
157
|
this.emit('exit', code, signal);
|
|
183
158
|
// in addition to the bare exit event, also emit one of three other
|
|
184
159
|
// events that contain more helpful information:
|
|
@@ -214,15 +189,12 @@ class SubProcess extends EventEmitter {
|
|
|
214
189
|
}
|
|
215
190
|
});
|
|
216
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* @deprecated This method is deprecated and will be removed
|
|
194
|
+
*/
|
|
217
195
|
handleLastLines() {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const lastLines = [this.lastLinePortion[stream]];
|
|
221
|
-
this.emit(`lines-${stream}`, lastLines);
|
|
222
|
-
this.emitLines(stream, lastLines);
|
|
223
|
-
this.lastLinePortion[stream] = '';
|
|
224
|
-
}
|
|
225
|
-
}
|
|
196
|
+
// TODO: THis is a noop left for backward compatibility.
|
|
197
|
+
// TODO: Remove it after the major version bump
|
|
226
198
|
}
|
|
227
199
|
/**
|
|
228
200
|
*
|
|
@@ -234,9 +206,6 @@ class SubProcess extends EventEmitter {
|
|
|
234
206
|
if (!this.isRunning) {
|
|
235
207
|
throw new Error(`Can't stop process; it's not currently running (cmd: '${this.rep}')`);
|
|
236
208
|
}
|
|
237
|
-
// make sure to emit any data in our lines buffer whenever we're done with
|
|
238
|
-
// the proc
|
|
239
|
-
this.handleLastLines();
|
|
240
209
|
return await new bluebird_1.default((resolve, reject) => {
|
|
241
210
|
this.proc?.on('close', resolve);
|
|
242
211
|
this.expectingExit = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../lib/subprocess.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../lib/subprocess.js"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export * from './lib/index';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export const MAX_BUFFER_SIZE = 100 * 1024 * 1024; // 100 MiB
|
|
2
|
+
const THRESHOLD = 0.15;
|
|
3
|
+
|
|
4
|
+
export class CircularBuffer {
|
|
5
|
+
private _buf: Buffer[];
|
|
6
|
+
private _size: number;
|
|
7
|
+
private _maxSize: number;
|
|
8
|
+
|
|
9
|
+
constructor(maxSize = MAX_BUFFER_SIZE) {
|
|
10
|
+
this._maxSize = maxSize;
|
|
11
|
+
this._buf = [];
|
|
12
|
+
this._size = 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get size(): number {
|
|
16
|
+
return this._size;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get count(): number {
|
|
20
|
+
return this._buf.length;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public add(item: Buffer): this {
|
|
24
|
+
this._buf.push(item);
|
|
25
|
+
this._size += item.length;
|
|
26
|
+
this._align();
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public value(): Buffer {
|
|
31
|
+
return Buffer.concat(this._buf);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private _align(): void {
|
|
35
|
+
if (this._size <= this._maxSize) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let numberOfItemsToShift = 0;
|
|
40
|
+
// We add the threshold to avoid shifting the array for each `add` call,
|
|
41
|
+
// which reduces the CPU usage
|
|
42
|
+
const expectedSizeToShift = this._size - this._maxSize + Math.trunc(this._maxSize * THRESHOLD);
|
|
43
|
+
let actualShiftedSize = 0;
|
|
44
|
+
while (numberOfItemsToShift < this._buf.length - 1 && actualShiftedSize <= expectedSizeToShift) {
|
|
45
|
+
actualShiftedSize += this._buf[numberOfItemsToShift].length;
|
|
46
|
+
numberOfItemsToShift++;
|
|
47
|
+
}
|
|
48
|
+
if (numberOfItemsToShift > 0) {
|
|
49
|
+
this._buf.splice(0, numberOfItemsToShift);
|
|
50
|
+
this._size -= actualShiftedSize;
|
|
51
|
+
}
|
|
52
|
+
if (actualShiftedSize < expectedSizeToShift) {
|
|
53
|
+
// We have already deleted all buffer items, but one,
|
|
54
|
+
// although the recent item is still too big to fit into the allowed size limit
|
|
55
|
+
const remainderToShift = expectedSizeToShift - actualShiftedSize;
|
|
56
|
+
this._buf[0] = this._buf[0].subarray(remainderToShift);
|
|
57
|
+
this._size -= remainderToShift;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
package/lib/exec.js
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
|
-
/* eslint-disable promise/prefer-await-to-callbacks */
|
|
2
|
-
|
|
3
1
|
import { spawn } from 'child_process';
|
|
4
2
|
import { quote } from 'shell-quote';
|
|
5
3
|
import B from 'bluebird';
|
|
6
4
|
import _ from 'lodash';
|
|
7
5
|
import { formatEnoent } from './helpers';
|
|
8
|
-
|
|
9
|
-
const MAX_BUFFER_SIZE = 100 * 1024 * 1024;
|
|
6
|
+
import { CircularBuffer, MAX_BUFFER_SIZE } from './circular-buffer';
|
|
10
7
|
|
|
11
8
|
/**
|
|
12
9
|
* Spawns a process
|
|
13
10
|
* @template {TeenProcessExecOptions} T
|
|
14
11
|
* @param {string} cmd - Program to execute
|
|
15
12
|
* @param {string[]} [args] - Arguments to pass to the program
|
|
16
|
-
* @param {T} [
|
|
13
|
+
* @param {T} [originalOpts] - Options
|
|
17
14
|
* @returns {Promise<BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult>}
|
|
18
15
|
*/
|
|
19
|
-
async function exec (cmd, args = [],
|
|
16
|
+
async function exec (cmd, args = [], originalOpts = /** @type {T} */({})) {
|
|
20
17
|
// get a quoted representation of the command for error strings
|
|
21
18
|
const rep = quote([cmd, ...args]);
|
|
22
19
|
|
|
23
20
|
// extend default options; we're basically re-implementing exec's options
|
|
24
21
|
// for use here with spawn under the hood
|
|
25
|
-
opts = /** @type {T} */(_.defaults(
|
|
22
|
+
const opts = /** @type {T} */(_.defaults(originalOpts, {
|
|
26
23
|
timeout: null,
|
|
27
24
|
encoding: 'utf8',
|
|
28
25
|
killSignal: 'SIGTERM',
|
|
@@ -43,8 +40,10 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
43
40
|
return await new B((resolve, reject) => {
|
|
44
41
|
// spawn the child process with options; we don't currently expose any of
|
|
45
42
|
// the other 'spawn' options through the API
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
const proc = spawn(cmd, args, {cwd: opts.cwd, env: opts.env, shell: opts.shell});
|
|
44
|
+
const stdoutBuffer = new CircularBuffer(opts.maxStdoutBufferSize);
|
|
45
|
+
const stderrBuffer = new CircularBuffer(opts.maxStderrBufferSize);
|
|
46
|
+
let timer = null;
|
|
48
47
|
|
|
49
48
|
// if the process errors out, reject the promise
|
|
50
49
|
proc.on('error', /** @param {NodeJS.ErrnoException} err */ async (err) => {
|
|
@@ -58,7 +57,7 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
58
57
|
reject(new Error(`Standard input '${err.syscall}' error: ${err.stack}`));
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
|
-
const handleStream = (streamType,
|
|
60
|
+
const handleStream = (/** @type {string} */ streamType, /** @type {CircularBuffer} */ buffer) => {
|
|
62
61
|
if (!proc[streamType]) {
|
|
63
62
|
return;
|
|
64
63
|
}
|
|
@@ -74,28 +73,15 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
74
73
|
}
|
|
75
74
|
|
|
76
75
|
// keep track of the stream if we don't want to ignore it
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
proc[streamType].on('data', (chunk) => {
|
|
80
|
-
chunks.push(chunk);
|
|
81
|
-
size += chunk.length;
|
|
82
|
-
while (chunks.length > 1 && size >= maxSize) {
|
|
83
|
-
size -= chunks[0].length;
|
|
84
|
-
chunks.shift();
|
|
85
|
-
}
|
|
76
|
+
proc[streamType].on('data', (/** @type {Buffer} */ chunk) => {
|
|
77
|
+
buffer.add(chunk);
|
|
86
78
|
if (opts.logger && _.isFunction(opts.logger.debug)) {
|
|
87
79
|
opts.logger.debug(chunk.toString());
|
|
88
80
|
}
|
|
89
81
|
});
|
|
90
82
|
};
|
|
91
|
-
handleStream('stdout',
|
|
92
|
-
|
|
93
|
-
chunks: stdoutArr,
|
|
94
|
-
});
|
|
95
|
-
handleStream('stderr', {
|
|
96
|
-
maxSize: opts.maxStderrBufferSize,
|
|
97
|
-
chunks: stderrArr,
|
|
98
|
-
});
|
|
83
|
+
handleStream('stdout', stdoutBuffer);
|
|
84
|
+
handleStream('stderr', stderrBuffer);
|
|
99
85
|
|
|
100
86
|
/**
|
|
101
87
|
* @template {boolean} U
|
|
@@ -103,15 +89,11 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
103
89
|
* @returns {U extends true ? {stdout: Buffer, stderr: Buffer} : {stdout: string, stderr: string}}
|
|
104
90
|
*/
|
|
105
91
|
function getStdio (isBuffer) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
stderr
|
|
110
|
-
|
|
111
|
-
stdout = Buffer.concat(stdoutArr).toString(opts.encoding);
|
|
112
|
-
stderr = Buffer.concat(stderrArr).toString(opts.encoding);
|
|
113
|
-
}
|
|
114
|
-
return /** @type {U extends true ? {stdout: Buffer, stderr: Buffer} : {stdout: string, stderr: string}} */({stdout, stderr});
|
|
92
|
+
const stdout = isBuffer ? stdoutBuffer.value() : stdoutBuffer.value().toString(opts.encoding);
|
|
93
|
+
const stderr = isBuffer ? stderrBuffer.value() : stderrBuffer.value().toString(opts.encoding);
|
|
94
|
+
return /** @type {U extends true ? {stdout: Buffer, stderr: Buffer} : {stdout: string, stderr: string}} */(
|
|
95
|
+
{stdout, stderr}
|
|
96
|
+
);
|
|
115
97
|
}
|
|
116
98
|
|
|
117
99
|
// if the process ends, either resolve or reject the promise based on the
|
|
@@ -121,7 +103,7 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
121
103
|
if (timer) {
|
|
122
104
|
clearTimeout(timer);
|
|
123
105
|
}
|
|
124
|
-
|
|
106
|
+
const {stdout, stderr} = getStdio(isBuffer);
|
|
125
107
|
if (code === 0) {
|
|
126
108
|
resolve(/** @type {BufferProp<T> extends true ? TeenProcessExecBufferResult : TeenProcessExecStringResult} */({stdout, stderr, code}));
|
|
127
109
|
} else {
|
|
@@ -136,7 +118,7 @@ async function exec (cmd, args = [], opts = /** @type {T} */({})) {
|
|
|
136
118
|
// have in case it's helpful in debugging
|
|
137
119
|
if (opts.timeout) {
|
|
138
120
|
timer = setTimeout(() => {
|
|
139
|
-
|
|
121
|
+
const {stdout, stderr} = getStdio(isBuffer);
|
|
140
122
|
let err = new Error(`Command '${rep}' timed out after ${opts.timeout}ms`);
|
|
141
123
|
err = Object.assign(err, {stdout, stderr, code: null});
|
|
142
124
|
reject(err);
|
package/lib/subprocess.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* eslint-disable promise/prefer-await-to-callbacks */
|
|
2
|
-
|
|
3
1
|
import { spawn } from 'child_process';
|
|
4
2
|
import events from 'events';
|
|
5
3
|
const { EventEmitter } = events;
|
|
@@ -7,28 +5,10 @@ import B from 'bluebird';
|
|
|
7
5
|
import { quote } from 'shell-quote';
|
|
8
6
|
import _ from 'lodash';
|
|
9
7
|
import { formatEnoent } from './helpers';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// This is needed to avoid memory leaks
|
|
13
|
-
// when the process output is too long and contains
|
|
14
|
-
// no line breaks
|
|
15
|
-
const MAX_LINE_PORTION_LENGTH = 0xFFFF;
|
|
16
|
-
|
|
17
|
-
function cutSuffix (str, suffixLength) {
|
|
18
|
-
return str.length > suffixLength
|
|
19
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
|
20
|
-
? ` ${str.substr(str.length - suffixLength)}`.substr(1)
|
|
21
|
-
: str;
|
|
22
|
-
}
|
|
23
|
-
|
|
8
|
+
import { createInterface } from 'node:readline';
|
|
24
9
|
|
|
25
10
|
class SubProcess extends EventEmitter {
|
|
26
11
|
|
|
27
|
-
/**
|
|
28
|
-
* @type { {stdout: string, stderr: string} }
|
|
29
|
-
*/
|
|
30
|
-
lastLinePortion;
|
|
31
|
-
|
|
32
12
|
/** @type {import('child_process').ChildProcess?} */
|
|
33
13
|
proc;
|
|
34
14
|
|
|
@@ -74,8 +54,6 @@ class SubProcess extends EventEmitter {
|
|
|
74
54
|
|
|
75
55
|
// get a quoted representation of the command for error strings
|
|
76
56
|
this.rep = quote([cmd, ...args]);
|
|
77
|
-
|
|
78
|
-
this.lastLinePortion = {stdout: '', stderr: ''};
|
|
79
57
|
}
|
|
80
58
|
|
|
81
59
|
get isRunning () {
|
|
@@ -85,18 +63,24 @@ class SubProcess extends EventEmitter {
|
|
|
85
63
|
|
|
86
64
|
/**
|
|
87
65
|
*
|
|
88
|
-
* @param {string}
|
|
89
|
-
* @param {Iterable<string
|
|
66
|
+
* @param {string} streamName
|
|
67
|
+
* @param {Iterable<string>|string} lines
|
|
90
68
|
*/
|
|
91
|
-
emitLines (
|
|
92
|
-
|
|
93
|
-
|
|
69
|
+
emitLines (streamName, lines) {
|
|
70
|
+
const doEmit = (/** @type {string} */ line) => this.emit('stream-line', `[${streamName.toUpperCase()}] ${line}`);
|
|
71
|
+
|
|
72
|
+
if (_.isString(lines)) {
|
|
73
|
+
doEmit(lines);
|
|
74
|
+
} else {
|
|
75
|
+
for (const line of lines) {
|
|
76
|
+
doEmit(line);
|
|
77
|
+
}
|
|
94
78
|
}
|
|
95
79
|
}
|
|
96
80
|
|
|
97
|
-
// spawn the subprocess and return control whenever we deem that it has fully
|
|
98
|
-
// "started"
|
|
99
81
|
/**
|
|
82
|
+
* spawn the subprocess and return control whenever we deem that it has fully
|
|
83
|
+
* "started"
|
|
100
84
|
*
|
|
101
85
|
* @param {StartDetector|number?} startDetector
|
|
102
86
|
* @param {number?} timeoutMs
|
|
@@ -148,7 +132,6 @@ class SubProcess extends EventEmitter {
|
|
|
148
132
|
if (this.proc.stderr) {
|
|
149
133
|
this.proc.stderr.setEncoding(this.opts.encoding || 'utf8');
|
|
150
134
|
}
|
|
151
|
-
this.lastLinePortion = {stdout: '', stderr: ''};
|
|
152
135
|
|
|
153
136
|
// this function handles output that we collect from the subproc
|
|
154
137
|
/**
|
|
@@ -170,31 +153,6 @@ class SubProcess extends EventEmitter {
|
|
|
170
153
|
|
|
171
154
|
// emit the actual output for whomever's listening
|
|
172
155
|
this.emit('output', stdout, stderr);
|
|
173
|
-
|
|
174
|
-
// we also want to emit lines, but it's more complex since output
|
|
175
|
-
// comes in chunks and a line could come in two different chunks, so
|
|
176
|
-
// we have logic to handle that case (using this.lastLinePortion to
|
|
177
|
-
// remember a line that started but did not finish in the last chunk)
|
|
178
|
-
for (const [streamName, streamData] of /** @type {[['stdout', string], ['stderr', string]]} */(_.toPairs(streams))) {
|
|
179
|
-
if (!streamData) continue; // eslint-disable-line curly
|
|
180
|
-
const lines = streamData.split('\n')
|
|
181
|
-
// https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
|
182
|
-
.map((x) => ` ${x}`.substr(1));
|
|
183
|
-
if (lines.length > 1) {
|
|
184
|
-
lines[0] = this.lastLinePortion[streamName] + lines[0];
|
|
185
|
-
this.lastLinePortion[streamName] = cutSuffix(_.last(lines), MAX_LINE_PORTION_LENGTH);
|
|
186
|
-
const resultLines = lines.slice(0, -1);
|
|
187
|
-
this.emit(`lines-${streamName}`, resultLines);
|
|
188
|
-
this.emitLines(streamName, resultLines);
|
|
189
|
-
} else {
|
|
190
|
-
const currentPortion = cutSuffix(lines[0], MAX_LINE_PORTION_LENGTH);
|
|
191
|
-
if (this.lastLinePortion[streamName].length + currentPortion.length > MAX_LINE_PORTION_LENGTH) {
|
|
192
|
-
this.lastLinePortion[streamName] = currentPortion;
|
|
193
|
-
} else {
|
|
194
|
-
this.lastLinePortion[streamName] += currentPortion;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
156
|
};
|
|
199
157
|
|
|
200
158
|
// if we get an error spawning the proc, reject and clean up the proc
|
|
@@ -211,20 +169,28 @@ class SubProcess extends EventEmitter {
|
|
|
211
169
|
this.proc = null;
|
|
212
170
|
});
|
|
213
171
|
|
|
172
|
+
const handleStreamLines = (/** @type {string} */ streamName, /** @type {import('stream').Readable} */ input) => {
|
|
173
|
+
const rl = createInterface({input});
|
|
174
|
+
rl.on('line', (line) => {
|
|
175
|
+
this.emit(`lines-${streamName}`, [line]);
|
|
176
|
+
this.emitLines(streamName, line);
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
|
|
214
180
|
if (this.proc.stdout) {
|
|
215
181
|
this.proc.stdout.on('data', (chunk) => handleOutput({stdout: chunk.toString(), stderr: ''}));
|
|
182
|
+
handleStreamLines('stdout', this.proc.stdout);
|
|
216
183
|
}
|
|
217
184
|
|
|
218
185
|
if (this.proc.stderr) {
|
|
219
186
|
this.proc.stderr.on('data', (chunk) => handleOutput({stdout: '', stderr: chunk.toString()}));
|
|
187
|
+
handleStreamLines('stderr', this.proc.stderr);
|
|
220
188
|
}
|
|
221
189
|
|
|
222
190
|
// when the proc exits, we might still have a buffer of lines we were
|
|
223
191
|
// waiting on more chunks to complete. Go ahead and emit those, then
|
|
224
192
|
// re-emit the exit so a listener can handle the possibly-unexpected exit
|
|
225
193
|
this.proc.on('exit', (code, signal) => {
|
|
226
|
-
this.handleLastLines();
|
|
227
|
-
|
|
228
194
|
this.emit('exit', code, signal);
|
|
229
195
|
|
|
230
196
|
// in addition to the bare exit event, also emit one of three other
|
|
@@ -265,15 +231,12 @@ class SubProcess extends EventEmitter {
|
|
|
265
231
|
});
|
|
266
232
|
}
|
|
267
233
|
|
|
234
|
+
/**
|
|
235
|
+
* @deprecated This method is deprecated and will be removed
|
|
236
|
+
*/
|
|
268
237
|
handleLastLines () {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
const lastLines = [this.lastLinePortion[stream]];
|
|
272
|
-
this.emit(`lines-${stream}`, lastLines);
|
|
273
|
-
this.emitLines(stream, lastLines);
|
|
274
|
-
this.lastLinePortion[stream] = '';
|
|
275
|
-
}
|
|
276
|
-
}
|
|
238
|
+
// TODO: THis is a noop left for backward compatibility.
|
|
239
|
+
// TODO: Remove it after the major version bump
|
|
277
240
|
}
|
|
278
241
|
|
|
279
242
|
/**
|
|
@@ -286,9 +249,6 @@ class SubProcess extends EventEmitter {
|
|
|
286
249
|
if (!this.isRunning) {
|
|
287
250
|
throw new Error(`Can't stop process; it's not currently running (cmd: '${this.rep}')`);
|
|
288
251
|
}
|
|
289
|
-
// make sure to emit any data in our lines buffer whenever we're done with
|
|
290
|
-
// the proc
|
|
291
|
-
this.handleLastLines();
|
|
292
252
|
return await new B((resolve, reject) => {
|
|
293
253
|
this.proc?.on('close', resolve);
|
|
294
254
|
this.expectingExit = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teen_process",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "A grown up version of Node's spawn/exec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"child_process",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"author": "Appium Contributors",
|
|
23
|
-
"main": "./index.js",
|
|
23
|
+
"main": "./build/index.js",
|
|
24
|
+
"types": "./build/index.d.ts",
|
|
24
25
|
"bin": {},
|
|
25
26
|
"directories": {
|
|
26
27
|
"lib": "lib"
|
|
@@ -53,15 +54,13 @@
|
|
|
53
54
|
"source-map-support": "^0.x"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@appium/eslint-config-appium": "^
|
|
57
|
+
"@appium/eslint-config-appium-ts": "^0.x",
|
|
57
58
|
"@appium/tsconfig": "^0.x",
|
|
58
59
|
"@appium/types": "^0.x",
|
|
59
60
|
"@semantic-release/changelog": "^6.0.3",
|
|
60
61
|
"@semantic-release/git": "^10.0.1",
|
|
61
62
|
"@types/bluebird": "^3.5.42",
|
|
62
|
-
"@types/chai-as-promised": "^7.1.8",
|
|
63
63
|
"@types/lodash": "^4.14.202",
|
|
64
|
-
"@types/mocha": "^10.0.6",
|
|
65
64
|
"@types/node": "^20.10.4",
|
|
66
65
|
"@types/shell-quote": "^1.7.5",
|
|
67
66
|
"@types/source-map-support": "^0.x",
|
|
@@ -72,8 +71,7 @@
|
|
|
72
71
|
"mocha": "^10.2.0",
|
|
73
72
|
"prettier": "^3.1.0",
|
|
74
73
|
"semantic-release": "^24.0.0",
|
|
75
|
-
"
|
|
76
|
-
"typescript": "~5.4",
|
|
74
|
+
"typescript": "^5.4.1",
|
|
77
75
|
"ts-node": "^10.9.1"
|
|
78
76
|
},
|
|
79
77
|
"engines": {
|