Skip to content

Commit 3319d3d

Browse files
committed
document spawning(), better catch handle all errors, additional tests,
1 parent f78e58f commit 3319d3d

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ This is mainly focused on initial installation of an Node JS packages that needs
1010

1111
`node-sys` will try to find which system packaging is installed for the given `process.platform`. If no system package manager is found, `'No package manager found!'` is returned.
1212

13+
A `spawning` cross-platform version of Node's child_process.`spawn` that returns a **Promise**.
14+
1315
## Install
1416

1517
```sh
@@ -54,6 +56,23 @@ installer('vim')
5456
});
5557
```
5658

59+
## API - spawning(command, arguments, progress, options)
60+
61+
`spawning` takes an additional argument, `progress`, its [`options`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) are the same as those of `child_process.spawn`.
62+
63+
* `progress`: callback handler for `stdout.on('data')` events.
64+
65+
It returns a promise whose result will be any output or any data return in the progress callback.
66+
*The progress callback will receive an object with these properties:*
67+
68+
* `handle:` *Object* - Spawned child process instance handler.
69+
* Access the child process object.
70+
71+
* `output:` *String* - Output from stdout.
72+
* Output can be altered and if returned will replace the otherwise resolved result.
73+
74+
If there's an error running the child process, received data on stderr, or errors in progress callback, `spawning` rejects the returned promise.
75+
5776
### CLI Usage
5877

5978
```s

index.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ export const spawning = Sys.spawning = function (cmd, argument = [], progress =
164164
return new Promise((resolve, reject) => {
165165
let output = null;
166166
const child = spawn(cmd, argument, options);
167+
child.on('error', (data) => {
168+
return reject(data);
169+
});
170+
167171
child.on('close', () => {
168172
return resolve(output);
169173
});
@@ -175,13 +179,17 @@ export const spawning = Sys.spawning = function (cmd, argument = [], progress =
175179
child.stdout.on('data', (data) => {
176180
let input = data.toString();
177181
let onProgress = null
178-
if (progress) {
179-
onProgress = progress({ handle: child, output: input });
182+
try {
183+
if (progress) {
184+
onProgress = progress({ handle: child, output: input });
185+
}
186+
} catch (e) {
187+
return reject(e.toString());
180188
}
181189

182-
if (onProgress) {
190+
if (onProgress && onProgress != null) {
183191
output = onProgress;
184-
} else {
192+
} else if (input != null) {
185193
output += input;
186194
}
187195

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "node-sys",
33
"version": "1.0.4",
4-
"description": "Universal package installer, get the command for managing packages, or auto install any package, using one command for all platforms. Automate the installation of macOS Brew, and Windows Chocolatey package managers.",
4+
"description": "Universal package installer, get the command for managing packages, or auto install any package, using one command for all platforms. Automate the installation of macOS Brew, and Windows Chocolatey package managers. A promisify child process of spawn.",
55
"type": "module",
66
"main": "index.js",
77
"bin": {
@@ -36,15 +36,17 @@
3636
"emerge",
3737
"zypper",
3838
"nix",
39-
"cross",
40-
"platform",
4139
"cross-platform",
4240
"package",
4341
"manager",
4442
"installer",
4543
"macOS",
4644
"windows",
47-
"linux"
45+
"linux",
46+
"spawn",
47+
"spawning",
48+
"child_process",
49+
"promisify"
4850
],
4951
"author": "l. stubbs <[email protected]>",
5052
"contributors": [

test/test.js

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import chai from 'chai';
22
import Sys from '../index.js';
3-
import { packager, installer, where } from '../index.js';
3+
import { packager, installer, where, spawning } from '../index.js';
44

55
const expect = chai.expect;
66

@@ -181,7 +181,7 @@ describe('Method: `installer` install packages `unzip`, platform set to `shell`'
181181
});
182182
});
183183

184-
describe('Method: `spawning`', function () {
184+
describe('Method: `installer` and progress callback, platform set to `win64`', function () {
185185
// save original process.platform
186186
before(function () {
187187
this.originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform');
@@ -215,6 +215,44 @@ describe('Method: `spawning`', function () {
215215
});
216216
});
217217

218+
describe('Method: `spawning`', function () {
219+
it('should return on successful install with output from `progress`', function (done) {
220+
spawning('echo', [''], (object) => {
221+
expect(object).to.be.a('object');
222+
expect(object.handle).to.be.instanceOf(Object);
223+
expect(object.output).to.be.a('string');
224+
return 'hello';
225+
}, { stdio: 'pipe', shell: true })
226+
.then(function (data) {
227+
expect(data).to.be.a('string');
228+
expect(data).to.equal('hello');
229+
done();
230+
})
231+
.catch(function (err) {
232+
expect(err).to.be.empty;
233+
done();
234+
});
235+
});
236+
237+
it('should catch error on throw from `progress`', function (done) {
238+
spawning('echo', [''], () => {
239+
throw 'hello';
240+
}, { stdio: 'pipe', shell: true })
241+
.catch(function (err) {
242+
expect(err).to.equal('hello');
243+
done();
244+
});
245+
});
246+
247+
it('should catch and instant of `Error` on any spawn exceptions', function (done) {
248+
spawning('xxxxx', [''], null, { stdio: 'pipe', })
249+
.catch(function (err) {
250+
expect(err).to.be.instanceof(Error);
251+
done();
252+
});
253+
});
254+
});
255+
218256
describe('Method: `where`', function () {
219257
it('should return null/empty for executable not found', function (done) {
220258
let found = where('fake-js');

0 commit comments

Comments
 (0)