@j-o-r/sh 1.1.24 → 1.1.25

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/lib/SHDispatch.js CHANGED
@@ -114,7 +114,7 @@ class SHDispatch {
114
114
  * @returns {SHDispatch}
115
115
  */
116
116
  options(options, prefix) {
117
- if (prefix && typeof prefix === 'string') {
117
+ if (typeof prefix === 'string') {
118
118
  this.#prefix = prefix;
119
119
  }
120
120
  if (options.stdio && typeof options.stdio === 'string') {
package/lib/SHExecute.js CHANGED
@@ -1,4 +1,4 @@
1
- import { spawnSync, spawn} from 'node:child_process';
1
+ import { spawnSync, spawn } from 'node:child_process';
2
2
 
3
3
  // Local helpers
4
4
  const isFinitePosInt = (n) => Number.isFinite(n) && n >= 0;
@@ -19,15 +19,13 @@ const parseDuration = (d) => {
19
19
  const childrenOf = (pid) => new Promise((resolve, reject) => {
20
20
  const p = spawn('pgrep', ['-P', String(pid)], { stdio: ['ignore', 'pipe', 'ignore'] });
21
21
  const out = [];
22
- p.stdout.on('data', (b) => out.push(b));
22
+ p.stdout.on('data', (chunk) => out.push(chunk));
23
23
  p.on('close', (code) => {
24
24
  if (code === 0) {
25
25
  const ids = Buffer.concat(out).toString('utf8').trim().split(/\s+/).map(Number).filter(Boolean);
26
26
  resolve(ids);
27
27
  } else if (code === 1) {
28
- resolve([]); // no children
29
- } else {
30
- reject(new Error(`pgrep -P ${pid} failed with code ${code}`));
28
+ resolve([]); // no children or error
31
29
  }
32
30
  });
33
31
  p.on('error', reject);
@@ -103,7 +101,7 @@ class SHExecute {
103
101
  const shellOpt = this.#options?.shell;
104
102
  if (shellOpt) {
105
103
  const sh = typeof shellOpt === 'string' ? shellOpt : 'bash';
106
- const cmd = `${this.#prefix}; ${this.#command}`;
104
+ const cmd = this.#prefix ? `${this.#prefix}; ${this.#command}` : this.#command;
107
105
  return spawnSync(sh, ['-c', cmd], options);
108
106
  }
109
107
  // no-shell mode
@@ -139,7 +137,7 @@ class SHExecute {
139
137
  const shellOpt = this.#options?.shell;
140
138
  if (shellOpt) {
141
139
  const sh = typeof shellOpt === 'string' ? shellOpt : 'bash';
142
- const cmd = `${this.#prefix}; ${this.#command}`;
140
+ const cmd = this.#prefix ? `${this.#prefix}; ${this.#command}` : this.#command;
143
141
  this.#proc = spawn(sh, ['-c', cmd], options);
144
142
  } else {
145
143
  this.#proc = spawn('/usr/bin/env', ['-S', this.#command], options);
@@ -199,9 +197,9 @@ class SHExecute {
199
197
  resolve(stdout);
200
198
  } else {
201
199
  const stderrBuf = this.#stderrChunks.length ? Buffer.concat(this.#stderrChunks) : Buffer.alloc(0);
202
- let stderr = stderrBuf.toString('utf8').trim();
200
+ let stderr = stderrBuf.toString('utf8');
203
201
  if (this.#truncated.stderr) stderr += '\n[stderr truncated]\n';
204
- reject(new Error(`Exit ${code ?? 'null'}${signal ? `, signal ${signal}` : ''}: ${this.#command}${stderr ? ` :: ${stderr}` : ''}`));
202
+ reject(new Error(`Command failed with code ${code}: ${stderr}`));
205
203
  }
206
204
  });
207
205
 
package/lib/Test.js CHANGED
@@ -140,7 +140,9 @@ class Test {
140
140
  const len = this.#tests.length;
141
141
  for (; i < len; i++) {
142
142
  this.#currentTest = i;
143
- if (execute && !execute.includes(i)) continue;
143
+ if (execute && !execute.includes(i)) {
144
+ continue;
145
+ }
144
146
  let duration = 0;
145
147
  let start = getNow();
146
148
  let executed = false;
@@ -179,9 +181,9 @@ class Test {
179
181
  return this.#report();
180
182
  }
181
183
  /**
182
- * @returns {Report}
184
+ * @returns {Promise<Report>}
183
185
  */
184
- #report() {
186
+ async #report() {
185
187
  let duration = 0;
186
188
  let executed = 0;
187
189
  const tests = this.#tests.length;
@@ -203,21 +205,29 @@ class Test {
203
205
  console.log(`Total: ${tests} tests, executed: ${executed} in ${duration} ms - errors: ${errors}`);
204
206
  if (tests !== executed) {
205
207
  if (!this.#quiet) console.log('** Not all tests have been executed **');
206
- return { tests, executed, duration, errors };
208
+ // return { tests, executed, duration, errors };
207
209
  }
208
210
  // Report on unresolved promises when NOT quiet
209
211
  // This must be on a next tick because the current Promise (where this code is in) is not resolved yet
210
- nextTick(() => {
211
- const count = this.#promiseTracker.report(true);
212
- if (count > 0) {
213
- console.log('--------------------------------------------------');
214
- console.log(`${count} Unresolved Promises detected.`);
215
- }
216
- });
212
+ setTimeout(() => {
213
+ const count = this.#promiseTracker.report(true);
214
+ if (count > 0) {
215
+ console.log('--------------------------------------------------');
216
+ console.log(`${count} Unresolved Promises detected.`);
217
+ }
218
+ }, 10);
217
219
  }
218
220
  return { tests, executed, duration, errors };
219
221
  }
220
222
 
223
+ unresolved() {
224
+ const count = this.#promiseTracker.report(true);
225
+ if (count > 0) {
226
+ console.log('--------------------------------------------------');
227
+ console.log(`${count} Unresolved Promises detected.`);
228
+ }
229
+ }
230
+
221
231
  /**
222
232
  * Empty tests
223
233
  */
@@ -225,6 +235,7 @@ class Test {
225
235
  this.#tests = [];
226
236
  this.#reports = [];
227
237
  this.#errors = [];
238
+ this.#promiseTracker.reset();
228
239
  }
229
240
  /**
230
241
  * Handle an error for the current test
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@j-o-r/sh",
3
3
  "author": "Jorrit Duin <j-o-r@duin.work>",
4
4
  "type": "module",
5
- "version": "1.1.24",
5
+ "version": "1.1.25",
6
6
  "description": "Execute shell commands on Linux-based systems from javascript",
7
7
  "main": "lib/SH.js",
8
8
  "types": "types/SH.d.ts",
package/types/Test.d.ts CHANGED
@@ -59,6 +59,7 @@ declare class Test {
59
59
  * @returns {Promise<Report>}
60
60
  */
61
61
  run(execute?: number[]): Promise<Report>;
62
+ unresolved(): void;
62
63
  /**
63
64
  * Empty tests
64
65
  */