@naturalcycles/nodejs-lib 13.34.3 → 13.34.5

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.
@@ -8,7 +8,7 @@ import { AnyObject, AppError, NumberOfMilliseconds } from '@naturalcycles/js-lib
8
8
  *
9
9
  * Short-running job, no need to print the output, might want to return the output - use Exec.
10
10
  *
11
- * Need to both print and return the output - use SpawnAsync.
11
+ * Need to both print and return the output - use SpawnAsyncAndReturn.
12
12
  *
13
13
  * ***
14
14
  *
@@ -23,55 +23,68 @@ import { AnyObject, AppError, NumberOfMilliseconds } from '@naturalcycles/js-lib
23
23
  */
24
24
  declare class Exec2 {
25
25
  /**
26
- * Advanced/async version of Spawn.
27
- * Consider simpler `spawn` or `exec` first, which are also sync.
28
- *
29
- * spawnAsync features:
26
+ * Reasons to use it:
27
+ * - Sync
28
+ * - Need to print output while running
30
29
  *
31
- * 1. Async
32
- * 2. Allows to collect the output AND print it while running.
33
- * 3. Returns SpawnOutput with stdout, stderr and exitCode.
34
- * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
30
+ * Limitations:
31
+ * - Cannot return stdout/stderr (use exec, execAsync or spawnAsyncAndReturn for that)
35
32
  *
36
33
  * Defaults:
37
34
  *
38
35
  * shell: true
39
- * printWhileRunning: true
40
- * collectOutputWhileRunning: true
41
- * throwOnNonZeroCode: true
42
36
  * log: true
43
37
  */
44
- spawnAsync(cmd: string, opt?: SpawnAsyncOptions): Promise<SpawnOutput>;
38
+ spawn(cmd: string, opt?: SpawnOptions): void;
45
39
  /**
46
40
  * Reasons to use it:
41
+ *
47
42
  * - Sync
43
+ * - Need to return output
44
+ *
45
+ * Limitations:
46
+ * - Cannot print while running (use spawn or spawnAsync for that)
47
+ *
48
+ * Defaults:
49
+ *
50
+ * shell: true
51
+ * log: false
52
+ */
53
+ exec(cmd: string, opt?: ExecOptions): string;
54
+ /**
55
+ * Reasons to use it:
56
+ * - Async
48
57
  * - Need to print output while running
49
58
  *
50
59
  * Limitations:
51
- * - Cannot return stdout/stderr (use exec or spawnAsync for that)
60
+ * - Cannot return stdout/stderr (use execAsync or spawnAsyncAndReturn for that)
52
61
  *
53
62
  * Defaults:
54
63
  *
55
64
  * shell: true
56
65
  * log: true
57
66
  */
58
- spawn(cmd: string, opt?: SpawnOptions): void;
67
+ spawnAsync(cmd: string, opt?: SpawnOptions): Promise<void>;
59
68
  /**
60
- * Reasons to use it:
69
+ * Advanced/async version of Spawn.
70
+ * Consider simpler `spawn` or `exec` first, which are also sync.
61
71
  *
62
- * - Sync
63
- * - Need to return output
72
+ * spawnAsyncAndReturn features:
64
73
  *
65
- * Limitations:
66
- * - Cannot print while running (use spawn or spawnAsync for that)
74
+ * 1. Async
75
+ * 2. Allows to collect the output AND print it while running.
76
+ * 3. Returns SpawnOutput with stdout, stderr and exitCode.
77
+ * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
67
78
  *
68
79
  * Defaults:
69
80
  *
70
81
  * shell: true
82
+ * printWhileRunning: true
83
+ * collectOutputWhileRunning: true
84
+ * throwOnNonZeroCode: true
71
85
  * log: true
72
86
  */
73
- exec(cmd: string, opt?: ExecOptions): string;
74
- throwOnNonZeroExitCode(o: SpawnOutput): void;
87
+ spawnAsyncAndReturn(cmd: string, opt?: SpawnAsyncOptions): Promise<SpawnOutput>;
75
88
  private logStart;
76
89
  private logFinish;
77
90
  }
@@ -14,7 +14,7 @@ const colors_1 = require("../colors/colors");
14
14
  *
15
15
  * Short-running job, no need to print the output, might want to return the output - use Exec.
16
16
  *
17
- * Need to both print and return the output - use SpawnAsync.
17
+ * Need to both print and return the output - use SpawnAsyncAndReturn.
18
18
  *
19
19
  * ***
20
20
  *
@@ -28,85 +28,13 @@ const colors_1 = require("../colors/colors");
28
28
  * Exec always uses the shell (there's no option to disable it).
29
29
  */
30
30
  class Exec2 {
31
- /**
32
- * Advanced/async version of Spawn.
33
- * Consider simpler `spawn` or `exec` first, which are also sync.
34
- *
35
- * spawnAsync features:
36
- *
37
- * 1. Async
38
- * 2. Allows to collect the output AND print it while running.
39
- * 3. Returns SpawnOutput with stdout, stderr and exitCode.
40
- * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
41
- *
42
- * Defaults:
43
- *
44
- * shell: true
45
- * printWhileRunning: true
46
- * collectOutputWhileRunning: true
47
- * throwOnNonZeroCode: true
48
- * log: true
49
- */
50
- async spawnAsync(cmd, opt = {}) {
51
- const { shell = true, printWhileRunning = true, collectOutputWhileRunning = true, throwOnNonZeroCode = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors, } = opt;
52
- opt.log ??= printWhileRunning; // by default log should be true, as we are printing the output
53
- const started = Date.now();
54
- this.logStart(cmd, opt);
55
- let stdout = '';
56
- let stderr = '';
57
- // if (printWhileRunning) console.log('') // 1-line padding before the output
58
- return await new Promise((resolve, reject) => {
59
- const p = node_child_process_1.default.spawn(cmd, opt.args || [], {
60
- shell,
61
- cwd,
62
- env: {
63
- ...(passProcessEnv ? process.env : {}),
64
- ...(forceColor ? { FORCE_COLOR: '1' } : {}),
65
- ...env,
66
- },
67
- });
68
- p.stdout.on('data', data => {
69
- if (collectOutputWhileRunning) {
70
- stdout += data.toString();
71
- // console.log('stdout:', data.toString())
72
- }
73
- if (printWhileRunning) {
74
- process.stdout.write(data);
75
- // console.log('stderr:', data.toString())
76
- }
77
- });
78
- p.stderr.on('data', data => {
79
- if (collectOutputWhileRunning) {
80
- stderr += data.toString();
81
- }
82
- if (printWhileRunning) {
83
- process.stderr.write(data);
84
- }
85
- });
86
- p.on('close', code => {
87
- // if (printWhileRunning) console.log('') // 1-line padding after the output
88
- const isSuccessful = !code;
89
- this.logFinish(cmd, opt, started, isSuccessful);
90
- const exitCode = code || 0;
91
- const o = {
92
- exitCode,
93
- stdout: stdout.trim(),
94
- stderr: stderr.trim(),
95
- };
96
- if (throwOnNonZeroCode && code) {
97
- return reject(new SpawnError(`spawnAsync exited with code ${code}: ${cmd}`, o));
98
- }
99
- resolve(o);
100
- });
101
- });
102
- }
103
31
  /**
104
32
  * Reasons to use it:
105
33
  * - Sync
106
34
  * - Need to print output while running
107
35
  *
108
36
  * Limitations:
109
- * - Cannot return stdout/stderr (use exec or spawnAsync for that)
37
+ * - Cannot return stdout/stderr (use exec, execAsync or spawnAsyncAndReturn for that)
110
38
  *
111
39
  * Defaults:
112
40
  *
@@ -116,9 +44,10 @@ class Exec2 {
116
44
  spawn(cmd, opt = {}) {
117
45
  const { shell = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors } = opt;
118
46
  opt.log ??= true; // by default log should be true, as we are printing the output
47
+ opt.logStart ??= opt.log;
48
+ opt.logFinish ??= opt.log;
119
49
  const started = Date.now();
120
50
  this.logStart(cmd, opt);
121
- // console.log('') // 1-line padding before the output
122
51
  const r = node_child_process_1.default.spawnSync(cmd, opt.args, {
123
52
  encoding: 'utf8',
124
53
  stdio: 'inherit',
@@ -130,7 +59,6 @@ class Exec2 {
130
59
  ...env,
131
60
  },
132
61
  });
133
- // console.log('') // 1-line padding after the output
134
62
  const isSuccessful = !r.error && !r.status;
135
63
  this.logFinish(cmd, opt, started, isSuccessful);
136
64
  if (r.error) {
@@ -152,12 +80,14 @@ class Exec2 {
152
80
  * Defaults:
153
81
  *
154
82
  * shell: true
155
- * log: true
83
+ * log: false
156
84
  */
157
85
  exec(cmd, opt = {}) {
86
+ const { cwd, env, passProcessEnv = true, timeout } = opt;
87
+ opt.logStart ??= opt.log ?? false;
88
+ opt.logFinish ??= opt.log ?? false;
158
89
  const started = Date.now();
159
90
  this.logStart(cmd, opt);
160
- const { cwd, env, passProcessEnv = true, timeout } = opt;
161
91
  try {
162
92
  const s = node_child_process_1.default
163
93
  .execSync(cmd, {
@@ -189,13 +119,121 @@ class Exec2 {
189
119
  throw new Error(`exec exited with code ${err.status}: ${cmd}`);
190
120
  }
191
121
  }
192
- throwOnNonZeroExitCode(o) {
193
- if (o.exitCode) {
194
- throw new SpawnError(`spawn exited with code ${o.exitCode}`, o);
195
- }
122
+ /**
123
+ * Reasons to use it:
124
+ * - Async
125
+ * - Need to print output while running
126
+ *
127
+ * Limitations:
128
+ * - Cannot return stdout/stderr (use execAsync or spawnAsyncAndReturn for that)
129
+ *
130
+ * Defaults:
131
+ *
132
+ * shell: true
133
+ * log: true
134
+ */
135
+ async spawnAsync(cmd, opt = {}) {
136
+ const { shell = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors } = opt;
137
+ opt.log ??= true; // by default log should be true, as we are printing the output
138
+ opt.logStart ??= opt.log;
139
+ opt.logFinish ??= opt.log;
140
+ const started = Date.now();
141
+ this.logStart(cmd, opt);
142
+ await new Promise((resolve, reject) => {
143
+ const p = node_child_process_1.default.spawn(cmd, opt.args || [], {
144
+ shell,
145
+ cwd,
146
+ stdio: 'inherit',
147
+ env: {
148
+ ...(passProcessEnv ? process.env : {}),
149
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
150
+ ...env,
151
+ },
152
+ });
153
+ p.on('close', code => {
154
+ const isSuccessful = !code;
155
+ this.logFinish(cmd, opt, started, isSuccessful);
156
+ if (code) {
157
+ return reject(new Error(`spawnAsync exited with code ${code}: ${cmd}`));
158
+ }
159
+ resolve();
160
+ });
161
+ });
162
+ }
163
+ /**
164
+ * Advanced/async version of Spawn.
165
+ * Consider simpler `spawn` or `exec` first, which are also sync.
166
+ *
167
+ * spawnAsyncAndReturn features:
168
+ *
169
+ * 1. Async
170
+ * 2. Allows to collect the output AND print it while running.
171
+ * 3. Returns SpawnOutput with stdout, stderr and exitCode.
172
+ * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
173
+ *
174
+ * Defaults:
175
+ *
176
+ * shell: true
177
+ * printWhileRunning: true
178
+ * collectOutputWhileRunning: true
179
+ * throwOnNonZeroCode: true
180
+ * log: true
181
+ */
182
+ async spawnAsyncAndReturn(cmd, opt = {}) {
183
+ const { shell = true, printWhileRunning = true, collectOutputWhileRunning = true, throwOnNonZeroCode = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors, } = opt;
184
+ opt.log ??= printWhileRunning; // by default log should be true, as we are printing the output
185
+ opt.logStart ??= opt.log;
186
+ opt.logFinish ??= opt.log;
187
+ const started = Date.now();
188
+ this.logStart(cmd, opt);
189
+ let stdout = '';
190
+ let stderr = '';
191
+ return await new Promise((resolve, reject) => {
192
+ const p = node_child_process_1.default.spawn(cmd, opt.args || [], {
193
+ shell,
194
+ cwd,
195
+ env: {
196
+ ...(passProcessEnv ? process.env : {}),
197
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
198
+ ...env,
199
+ },
200
+ });
201
+ p.stdout.on('data', data => {
202
+ if (collectOutputWhileRunning) {
203
+ stdout += data.toString();
204
+ // console.log('stdout:', data.toString())
205
+ }
206
+ if (printWhileRunning) {
207
+ process.stdout.write(data);
208
+ // console.log('stderr:', data.toString())
209
+ }
210
+ });
211
+ p.stderr.on('data', data => {
212
+ if (collectOutputWhileRunning) {
213
+ stderr += data.toString();
214
+ }
215
+ if (printWhileRunning) {
216
+ process.stderr.write(data);
217
+ }
218
+ });
219
+ p.on('close', code => {
220
+ const isSuccessful = !code;
221
+ this.logFinish(cmd, opt, started, isSuccessful);
222
+ const exitCode = code || 0;
223
+ const o = {
224
+ exitCode,
225
+ stdout: stdout.trim(),
226
+ stderr: stderr.trim(),
227
+ };
228
+ if (throwOnNonZeroCode && code) {
229
+ return reject(new SpawnError(`spawnAsyncAndReturn exited with code ${code}: ${cmd}`, o));
230
+ }
231
+ resolve(o);
232
+ });
233
+ });
196
234
  }
197
235
  logStart(cmd, opt) {
198
- if (!opt.logStart && !opt.log)
236
+ if (!opt.logStart)
199
237
  return;
200
238
  console.log([
201
239
  (0, colors_1.dimGrey)(...Object.entries(opt.env || {}).map(([k, v]) => [k, v].join('='))),
@@ -206,7 +244,7 @@ class Exec2 {
206
244
  .join(' '));
207
245
  }
208
246
  logFinish(cmd, opt, started, isSuccessful) {
209
- if (isSuccessful && !opt.logFinish && !opt.log)
247
+ if (isSuccessful && !opt.logFinish)
210
248
  return;
211
249
  console.log([
212
250
  (0, colors_1.white)(opt.name || cmd),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
- "version": "13.34.3",
3
+ "version": "13.34.5",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build": "dev-lib build",
package/src/util/exec2.ts CHANGED
@@ -17,7 +17,7 @@ import { dimGrey, dimRed, hasColors, white } from '../colors/colors'
17
17
  *
18
18
  * Short-running job, no need to print the output, might want to return the output - use Exec.
19
19
  *
20
- * Need to both print and return the output - use SpawnAsync.
20
+ * Need to both print and return the output - use SpawnAsyncAndReturn.
21
21
  *
22
22
  * ***
23
23
  *
@@ -31,99 +31,13 @@ import { dimGrey, dimRed, hasColors, white } from '../colors/colors'
31
31
  * Exec always uses the shell (there's no option to disable it).
32
32
  */
33
33
  class Exec2 {
34
- /**
35
- * Advanced/async version of Spawn.
36
- * Consider simpler `spawn` or `exec` first, which are also sync.
37
- *
38
- * spawnAsync features:
39
- *
40
- * 1. Async
41
- * 2. Allows to collect the output AND print it while running.
42
- * 3. Returns SpawnOutput with stdout, stderr and exitCode.
43
- * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
44
- *
45
- * Defaults:
46
- *
47
- * shell: true
48
- * printWhileRunning: true
49
- * collectOutputWhileRunning: true
50
- * throwOnNonZeroCode: true
51
- * log: true
52
- */
53
- async spawnAsync(cmd: string, opt: SpawnAsyncOptions = {}): Promise<SpawnOutput> {
54
- const {
55
- shell = true,
56
- printWhileRunning = true,
57
- collectOutputWhileRunning = true,
58
- throwOnNonZeroCode = true,
59
- cwd,
60
- env,
61
- passProcessEnv = true,
62
- forceColor = hasColors,
63
- } = opt
64
- opt.log ??= printWhileRunning // by default log should be true, as we are printing the output
65
- const started = Date.now()
66
- this.logStart(cmd, opt)
67
- let stdout = ''
68
- let stderr = ''
69
-
70
- // if (printWhileRunning) console.log('') // 1-line padding before the output
71
-
72
- return await new Promise<SpawnOutput>((resolve, reject) => {
73
- const p = cp.spawn(cmd, opt.args || [], {
74
- shell,
75
- cwd,
76
- env: {
77
- ...(passProcessEnv ? process.env : {}),
78
- ...(forceColor ? { FORCE_COLOR: '1' } : {}),
79
- ...env,
80
- },
81
- })
82
-
83
- p.stdout.on('data', data => {
84
- if (collectOutputWhileRunning) {
85
- stdout += data.toString()
86
- // console.log('stdout:', data.toString())
87
- }
88
- if (printWhileRunning) {
89
- process.stdout.write(data)
90
- // console.log('stderr:', data.toString())
91
- }
92
- })
93
- p.stderr.on('data', data => {
94
- if (collectOutputWhileRunning) {
95
- stderr += data.toString()
96
- }
97
- if (printWhileRunning) {
98
- process.stderr.write(data)
99
- }
100
- })
101
-
102
- p.on('close', code => {
103
- // if (printWhileRunning) console.log('') // 1-line padding after the output
104
- const isSuccessful = !code
105
- this.logFinish(cmd, opt, started, isSuccessful)
106
- const exitCode = code || 0
107
- const o: SpawnOutput = {
108
- exitCode,
109
- stdout: stdout.trim(),
110
- stderr: stderr.trim(),
111
- }
112
- if (throwOnNonZeroCode && code) {
113
- return reject(new SpawnError(`spawnAsync exited with code ${code}: ${cmd}`, o))
114
- }
115
- resolve(o)
116
- })
117
- })
118
- }
119
-
120
34
  /**
121
35
  * Reasons to use it:
122
36
  * - Sync
123
37
  * - Need to print output while running
124
38
  *
125
39
  * Limitations:
126
- * - Cannot return stdout/stderr (use exec or spawnAsync for that)
40
+ * - Cannot return stdout/stderr (use exec, execAsync or spawnAsyncAndReturn for that)
127
41
  *
128
42
  * Defaults:
129
43
  *
@@ -133,9 +47,10 @@ class Exec2 {
133
47
  spawn(cmd: string, opt: SpawnOptions = {}): void {
134
48
  const { shell = true, cwd, env, passProcessEnv = true, forceColor = hasColors } = opt
135
49
  opt.log ??= true // by default log should be true, as we are printing the output
50
+ opt.logStart ??= opt.log
51
+ opt.logFinish ??= opt.log
136
52
  const started = Date.now()
137
53
  this.logStart(cmd, opt)
138
- // console.log('') // 1-line padding before the output
139
54
 
140
55
  const r = cp.spawnSync(cmd, opt.args, {
141
56
  encoding: 'utf8',
@@ -149,7 +64,6 @@ class Exec2 {
149
64
  },
150
65
  })
151
66
 
152
- // console.log('') // 1-line padding after the output
153
67
  const isSuccessful = !r.error && !r.status
154
68
  this.logFinish(cmd, opt, started, isSuccessful)
155
69
 
@@ -173,12 +87,14 @@ class Exec2 {
173
87
  * Defaults:
174
88
  *
175
89
  * shell: true
176
- * log: true
90
+ * log: false
177
91
  */
178
92
  exec(cmd: string, opt: ExecOptions = {}): string {
93
+ const { cwd, env, passProcessEnv = true, timeout } = opt
94
+ opt.logStart ??= opt.log ?? false
95
+ opt.logFinish ??= opt.log ?? false
179
96
  const started = Date.now()
180
97
  this.logStart(cmd, opt)
181
- const { cwd, env, passProcessEnv = true, timeout } = opt
182
98
 
183
99
  try {
184
100
  const s = cp
@@ -212,14 +128,137 @@ class Exec2 {
212
128
  }
213
129
  }
214
130
 
215
- throwOnNonZeroExitCode(o: SpawnOutput): void {
216
- if (o.exitCode) {
217
- throw new SpawnError(`spawn exited with code ${o.exitCode}`, o)
218
- }
131
+ /**
132
+ * Reasons to use it:
133
+ * - Async
134
+ * - Need to print output while running
135
+ *
136
+ * Limitations:
137
+ * - Cannot return stdout/stderr (use execAsync or spawnAsyncAndReturn for that)
138
+ *
139
+ * Defaults:
140
+ *
141
+ * shell: true
142
+ * log: true
143
+ */
144
+ async spawnAsync(cmd: string, opt: SpawnOptions = {}): Promise<void> {
145
+ const { shell = true, cwd, env, passProcessEnv = true, forceColor = hasColors } = opt
146
+ opt.log ??= true // by default log should be true, as we are printing the output
147
+ opt.logStart ??= opt.log
148
+ opt.logFinish ??= opt.log
149
+ const started = Date.now()
150
+ this.logStart(cmd, opt)
151
+
152
+ await new Promise<void>((resolve, reject) => {
153
+ const p = cp.spawn(cmd, opt.args || [], {
154
+ shell,
155
+ cwd,
156
+ stdio: 'inherit',
157
+ env: {
158
+ ...(passProcessEnv ? process.env : {}),
159
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
160
+ ...env,
161
+ },
162
+ })
163
+
164
+ p.on('close', code => {
165
+ const isSuccessful = !code
166
+ this.logFinish(cmd, opt, started, isSuccessful)
167
+ if (code) {
168
+ return reject(new Error(`spawnAsync exited with code ${code}: ${cmd}`))
169
+ }
170
+ resolve()
171
+ })
172
+ })
173
+ }
174
+
175
+ /**
176
+ * Advanced/async version of Spawn.
177
+ * Consider simpler `spawn` or `exec` first, which are also sync.
178
+ *
179
+ * spawnAsyncAndReturn features:
180
+ *
181
+ * 1. Async
182
+ * 2. Allows to collect the output AND print it while running.
183
+ * 3. Returns SpawnOutput with stdout, stderr and exitCode.
184
+ * 4. Allows to not throw on error, but just return SpawnOutput for further inspection.
185
+ *
186
+ * Defaults:
187
+ *
188
+ * shell: true
189
+ * printWhileRunning: true
190
+ * collectOutputWhileRunning: true
191
+ * throwOnNonZeroCode: true
192
+ * log: true
193
+ */
194
+ async spawnAsyncAndReturn(cmd: string, opt: SpawnAsyncOptions = {}): Promise<SpawnOutput> {
195
+ const {
196
+ shell = true,
197
+ printWhileRunning = true,
198
+ collectOutputWhileRunning = true,
199
+ throwOnNonZeroCode = true,
200
+ cwd,
201
+ env,
202
+ passProcessEnv = true,
203
+ forceColor = hasColors,
204
+ } = opt
205
+ opt.log ??= printWhileRunning // by default log should be true, as we are printing the output
206
+ opt.logStart ??= opt.log
207
+ opt.logFinish ??= opt.log
208
+ const started = Date.now()
209
+ this.logStart(cmd, opt)
210
+ let stdout = ''
211
+ let stderr = ''
212
+
213
+ return await new Promise<SpawnOutput>((resolve, reject) => {
214
+ const p = cp.spawn(cmd, opt.args || [], {
215
+ shell,
216
+ cwd,
217
+ env: {
218
+ ...(passProcessEnv ? process.env : {}),
219
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
220
+ ...env,
221
+ },
222
+ })
223
+
224
+ p.stdout.on('data', data => {
225
+ if (collectOutputWhileRunning) {
226
+ stdout += data.toString()
227
+ // console.log('stdout:', data.toString())
228
+ }
229
+ if (printWhileRunning) {
230
+ process.stdout.write(data)
231
+ // console.log('stderr:', data.toString())
232
+ }
233
+ })
234
+ p.stderr.on('data', data => {
235
+ if (collectOutputWhileRunning) {
236
+ stderr += data.toString()
237
+ }
238
+ if (printWhileRunning) {
239
+ process.stderr.write(data)
240
+ }
241
+ })
242
+
243
+ p.on('close', code => {
244
+ const isSuccessful = !code
245
+ this.logFinish(cmd, opt, started, isSuccessful)
246
+ const exitCode = code || 0
247
+ const o: SpawnOutput = {
248
+ exitCode,
249
+ stdout: stdout.trim(),
250
+ stderr: stderr.trim(),
251
+ }
252
+ if (throwOnNonZeroCode && code) {
253
+ return reject(new SpawnError(`spawnAsyncAndReturn exited with code ${code}: ${cmd}`, o))
254
+ }
255
+ resolve(o)
256
+ })
257
+ })
219
258
  }
220
259
 
221
260
  private logStart(cmd: string, opt: SpawnOptions | ExecOptions): void {
222
- if (!opt.logStart && !opt.log) return
261
+ if (!opt.logStart) return
223
262
 
224
263
  console.log(
225
264
  [
@@ -238,7 +277,7 @@ class Exec2 {
238
277
  started: UnixTimestampMillisNumber,
239
278
  isSuccessful: boolean,
240
279
  ): void {
241
- if (isSuccessful && !opt.logFinish && !opt.log) return
280
+ if (isSuccessful && !opt.logFinish) return
242
281
 
243
282
  console.log(
244
283
  [