@naturalcycles/nodejs-lib 13.34.0 → 13.34.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.
@@ -141,10 +141,15 @@ export interface SpawnOptions {
141
141
  cwd?: string;
142
142
  env?: AnyObject;
143
143
  /**
144
- * Defaults to false for security reasons.
145
- * Set to true to pass `process.env` to the spawned process.
144
+ * Defaults to true.
145
+ * Set to false to NOT pass `process.env` to the spawned process.
146
146
  */
147
147
  passProcessEnv?: boolean;
148
+ /**
149
+ * Defaults to "auto detect colors".
150
+ * Set to false or true to override.
151
+ */
152
+ forceColor?: boolean;
148
153
  }
149
154
  export interface ExecOptions {
150
155
  /**
@@ -50,16 +50,19 @@ class Exec2 {
50
50
  async spawnAsync(cmd, opt = {}) {
51
51
  const started = Date.now();
52
52
  this.logStart(cmd, opt);
53
- const { shell = true, printWhileRunning = true, collectOutputWhileRunning = true, throwOnNonZeroCode = true, cwd, env, } = opt;
53
+ const { shell = true, printWhileRunning = true, collectOutputWhileRunning = true, throwOnNonZeroCode = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors, } = opt;
54
54
  let stdout = '';
55
55
  let stderr = '';
56
+ if (printWhileRunning)
57
+ console.log(''); // 1-line padding before the output
56
58
  return await new Promise((resolve, reject) => {
57
59
  const p = node_child_process_1.default.spawn(cmd, opt.args || [], {
58
60
  shell,
59
61
  cwd,
60
62
  env: {
63
+ ...(passProcessEnv ? process.env : {}),
64
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
61
65
  ...env,
62
- ...(opt.passProcessEnv ? process.env : {}),
63
66
  },
64
67
  });
65
68
  p.stdout.on('data', data => {
@@ -81,7 +84,10 @@ class Exec2 {
81
84
  }
82
85
  });
83
86
  p.on('close', code => {
84
- this.logFinish(cmd, opt, started);
87
+ if (printWhileRunning)
88
+ console.log(''); // 1-line padding after the output
89
+ const isSuccessful = !code;
90
+ this.logFinish(cmd, opt, started, isSuccessful);
85
91
  const exitCode = code || 0;
86
92
  const o = {
87
93
  exitCode,
@@ -111,18 +117,22 @@ class Exec2 {
111
117
  spawn(cmd, opt = {}) {
112
118
  const started = Date.now();
113
119
  this.logStart(cmd, opt);
114
- const { shell = true, cwd, env } = opt;
120
+ const { shell = true, cwd, env, passProcessEnv = true, forceColor = colors_1.hasColors } = opt;
121
+ console.log(''); // 1-line padding before the output
115
122
  const r = node_child_process_1.default.spawnSync(cmd, opt.args, {
116
123
  encoding: 'utf8',
117
124
  stdio: 'inherit',
118
125
  shell,
119
126
  cwd,
120
127
  env: {
128
+ ...(passProcessEnv ? process.env : {}),
129
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
121
130
  ...env,
122
- ...(opt.passProcessEnv ? process.env : {}),
123
131
  },
124
132
  });
125
- this.logFinish(cmd, opt, started);
133
+ console.log(''); // 1-line padding after the output
134
+ const isSuccessful = !r.error && !r.status;
135
+ this.logFinish(cmd, opt, started, isSuccessful);
126
136
  if (r.error) {
127
137
  throw r.error;
128
138
  }
@@ -147,9 +157,9 @@ class Exec2 {
147
157
  exec(cmd, opt = {}) {
148
158
  const started = Date.now();
149
159
  this.logStart(cmd, opt);
150
- const { cwd, env, timeout } = opt;
160
+ const { cwd, env, passProcessEnv = true, timeout } = opt;
151
161
  try {
152
- return node_child_process_1.default
162
+ const s = node_child_process_1.default
153
163
  .execSync(cmd, {
154
164
  encoding: 'utf8',
155
165
  // stdio: 'inherit', // no, otherwise we don't get the output returned
@@ -158,11 +168,13 @@ class Exec2 {
158
168
  cwd,
159
169
  timeout,
160
170
  env: {
171
+ ...(passProcessEnv ? process.env : {}),
161
172
  ...env,
162
- ...(opt.passProcessEnv ? process.env : {}),
163
173
  },
164
174
  })
165
175
  .trim();
176
+ this.logFinish(cmd, opt, started, true);
177
+ return s;
166
178
  }
167
179
  catch (err) {
168
180
  // Not logging stderr, as it's printed by execSync by default (somehow)
@@ -173,11 +185,9 @@ class Exec2 {
173
185
  if (err.stdout) {
174
186
  process.stdout.write(err.stdout);
175
187
  }
188
+ this.logFinish(cmd, opt, started, false);
176
189
  throw new Error(`exec exited with code ${err.status}: ${cmd}`);
177
190
  }
178
- finally {
179
- this.logFinish(cmd, opt, started);
180
- }
181
191
  }
182
192
  throwOnNonZeroExitCode(o) {
183
193
  if (o.exitCode) {
@@ -195,13 +205,14 @@ class Exec2 {
195
205
  .filter(Boolean)
196
206
  .join(' '));
197
207
  }
198
- logFinish(cmd, opt, started) {
199
- if (!opt.logFinish && !opt.log)
208
+ logFinish(cmd, opt, started, isSuccessful) {
209
+ if (isSuccessful && !opt.logFinish && !opt.log)
200
210
  return;
201
211
  console.log([
202
212
  (0, colors_1.white)(opt.name || cmd),
203
213
  ...((!opt.name && opt.args) || []),
204
214
  (0, colors_1.dimGrey)('took ' + (0, js_lib_1._since)(started)),
215
+ !isSuccessful && (0, colors_1.dimGrey)('and ') + (0, colors_1.dimRed)('failed'),
205
216
  ]
206
217
  .filter(Boolean)
207
218
  .join(' '));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
- "version": "13.34.0",
3
+ "version": "13.34.2",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build": "dev-lib build",
package/src/util/exec2.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  NumberOfMilliseconds,
7
7
  UnixTimestampMillisNumber,
8
8
  } from '@naturalcycles/js-lib'
9
- import { dimGrey, white } from '../colors/colors'
9
+ import { dimGrey, dimRed, hasColors, white } from '../colors/colors'
10
10
 
11
11
  /**
12
12
  * Set of utility functions to work with Spawn / Exec.
@@ -60,17 +60,22 @@ class Exec2 {
60
60
  throwOnNonZeroCode = true,
61
61
  cwd,
62
62
  env,
63
+ passProcessEnv = true,
64
+ forceColor = hasColors,
63
65
  } = opt
64
66
  let stdout = ''
65
67
  let stderr = ''
66
68
 
69
+ if (printWhileRunning) console.log('') // 1-line padding before the output
70
+
67
71
  return await new Promise<SpawnOutput>((resolve, reject) => {
68
72
  const p = cp.spawn(cmd, opt.args || [], {
69
73
  shell,
70
74
  cwd,
71
75
  env: {
76
+ ...(passProcessEnv ? process.env : {}),
77
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
72
78
  ...env,
73
- ...(opt.passProcessEnv ? process.env : {}),
74
79
  },
75
80
  })
76
81
 
@@ -94,7 +99,9 @@ class Exec2 {
94
99
  })
95
100
 
96
101
  p.on('close', code => {
97
- this.logFinish(cmd, opt, started)
102
+ if (printWhileRunning) console.log('') // 1-line padding after the output
103
+ const isSuccessful = !code
104
+ this.logFinish(cmd, opt, started, isSuccessful)
98
105
  const exitCode = code || 0
99
106
  const o: SpawnOutput = {
100
107
  exitCode,
@@ -125,7 +132,8 @@ class Exec2 {
125
132
  spawn(cmd: string, opt: SpawnOptions = {}): void {
126
133
  const started = Date.now()
127
134
  this.logStart(cmd, opt)
128
- const { shell = true, cwd, env } = opt
135
+ const { shell = true, cwd, env, passProcessEnv = true, forceColor = hasColors } = opt
136
+ console.log('') // 1-line padding before the output
129
137
 
130
138
  const r = cp.spawnSync(cmd, opt.args, {
131
139
  encoding: 'utf8',
@@ -133,12 +141,15 @@ class Exec2 {
133
141
  shell,
134
142
  cwd,
135
143
  env: {
144
+ ...(passProcessEnv ? process.env : {}),
145
+ ...(forceColor ? { FORCE_COLOR: '1' } : {}),
136
146
  ...env,
137
- ...(opt.passProcessEnv ? process.env : {}),
138
147
  },
139
148
  })
140
149
 
141
- this.logFinish(cmd, opt, started)
150
+ console.log('') // 1-line padding after the output
151
+ const isSuccessful = !r.error && !r.status
152
+ this.logFinish(cmd, opt, started, isSuccessful)
142
153
 
143
154
  if (r.error) {
144
155
  throw r.error
@@ -165,10 +176,10 @@ class Exec2 {
165
176
  exec(cmd: string, opt: ExecOptions = {}): string {
166
177
  const started = Date.now()
167
178
  this.logStart(cmd, opt)
168
- const { cwd, env, timeout } = opt
179
+ const { cwd, env, passProcessEnv = true, timeout } = opt
169
180
 
170
181
  try {
171
- return cp
182
+ const s = cp
172
183
  .execSync(cmd, {
173
184
  encoding: 'utf8',
174
185
  // stdio: 'inherit', // no, otherwise we don't get the output returned
@@ -177,11 +188,14 @@ class Exec2 {
177
188
  cwd,
178
189
  timeout,
179
190
  env: {
191
+ ...(passProcessEnv ? process.env : {}),
180
192
  ...env,
181
- ...(opt.passProcessEnv ? process.env : {}),
182
193
  },
183
194
  })
184
195
  .trim()
196
+
197
+ this.logFinish(cmd, opt, started, true)
198
+ return s
185
199
  } catch (err) {
186
200
  // Not logging stderr, as it's printed by execSync by default (somehow)
187
201
  // stdout is not printed by execSync though, therefor we print it here
@@ -191,9 +205,8 @@ class Exec2 {
191
205
  if ((err as any).stdout) {
192
206
  process.stdout.write((err as any).stdout)
193
207
  }
208
+ this.logFinish(cmd, opt, started, false)
194
209
  throw new Error(`exec exited with code ${(err as any).status}: ${cmd}`)
195
- } finally {
196
- this.logFinish(cmd, opt, started)
197
210
  }
198
211
  }
199
212
 
@@ -221,14 +234,16 @@ class Exec2 {
221
234
  cmd: string,
222
235
  opt: SpawnOptions | ExecOptions,
223
236
  started: UnixTimestampMillisNumber,
237
+ isSuccessful: boolean,
224
238
  ): void {
225
- if (!opt.logFinish && !opt.log) return
239
+ if (isSuccessful && !opt.logFinish && !opt.log) return
226
240
 
227
241
  console.log(
228
242
  [
229
243
  white(opt.name || cmd),
230
244
  ...((!opt.name && (opt as SpawnOptions).args) || []),
231
245
  dimGrey('took ' + _since(started)),
246
+ !isSuccessful && dimGrey('and ') + dimRed('failed'),
232
247
  ]
233
248
  .filter(Boolean)
234
249
  .join(' '),
@@ -312,10 +327,15 @@ export interface SpawnOptions {
312
327
 
313
328
  env?: AnyObject
314
329
  /**
315
- * Defaults to false for security reasons.
316
- * Set to true to pass `process.env` to the spawned process.
330
+ * Defaults to true.
331
+ * Set to false to NOT pass `process.env` to the spawned process.
317
332
  */
318
333
  passProcessEnv?: boolean
334
+ /**
335
+ * Defaults to "auto detect colors".
336
+ * Set to false or true to override.
337
+ */
338
+ forceColor?: boolean
319
339
  }
320
340
 
321
341
  export interface ExecOptions {