@zhennann/common-bin 3.0.0 → 4.0.1
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/README.md +20 -21
- package/index.d.ts +1 -1
- package/lib/command.js +18 -17
- package/lib/helper.js +6 -6
- package/package.json +17 -33
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# common-bin
|
|
2
2
|
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
|
4
|
+
[](https://github.com/node-modules/common-bin/actions/workflows/nodejs.yml)
|
|
4
5
|
[![Test coverage][codecov-image]][codecov-url]
|
|
5
6
|
[![Known Vulnerabilities][snyk-image]][snyk-url]
|
|
6
7
|
[![npm download][download-image]][download-url]
|
|
@@ -14,7 +15,7 @@
|
|
|
14
15
|
[download-image]: https://img.shields.io/npm/dm/common-bin.svg?style=flat-square
|
|
15
16
|
[download-url]: https://npmjs.org/package/common-bin
|
|
16
17
|
|
|
17
|
-
Abstraction bin tool wrap [yargs](http://yargs.js.org/), to provide more convenient usage, support async /
|
|
18
|
+
Abstraction bin tool wrap [yargs](http://yargs.js.org/), to provide more convenient usage, support async / await style.
|
|
18
19
|
|
|
19
20
|
---
|
|
20
21
|
|
|
@@ -106,7 +107,7 @@ class CloneCommand extends Command {
|
|
|
106
107
|
};
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
async run({ argv }) {
|
|
110
111
|
console.log('git clone %s to %s with depth %d', argv._[0], argv._[1], argv.depth);
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -134,8 +135,8 @@ Define the main logic of command
|
|
|
134
135
|
|
|
135
136
|
**Method:**
|
|
136
137
|
|
|
137
|
-
- `start()` - start your program, only use once in your bin file.
|
|
138
|
-
- `run(context)`
|
|
138
|
+
- `async start()` - start your program, only use once in your bin file.
|
|
139
|
+
- `async run(context)`
|
|
139
140
|
- should implement this to provide command handler, will exec when not found sub command.
|
|
140
141
|
- Support generator / async function / normal function which return promise.
|
|
141
142
|
- `context` is `{ cwd, env, argv, rawArgv }`
|
|
@@ -194,10 +195,10 @@ get version() {
|
|
|
194
195
|
|
|
195
196
|
### Helper
|
|
196
197
|
|
|
197
|
-
- `forkNode(modulePath, args, opt)` - fork child process, wrap with promise and gracefull exit
|
|
198
|
-
- `spawn(cmd, args, opt)` - spawn a new process, wrap with promise and gracefull exit
|
|
199
|
-
- `npmInstall(npmCli, name, cwd)` - install node modules, wrap with promise
|
|
200
|
-
-
|
|
198
|
+
- `async forkNode(modulePath, args, opt)` - fork child process, wrap with promise and gracefull exit
|
|
199
|
+
- `async spawn(cmd, args, opt)` - spawn a new process, wrap with promise and gracefull exit
|
|
200
|
+
- `async npmInstall(npmCli, name, cwd)` - install node modules, wrap with promise
|
|
201
|
+
- `async callFn(fn, args, thisArg)` - call fn, support gernerator / async / normal function return promise
|
|
201
202
|
- `unparseArgv(argv, opts)` - unparse argv and change it to array style
|
|
202
203
|
|
|
203
204
|
**Extend Helper**
|
|
@@ -237,7 +238,7 @@ class MainCommand extends Command {
|
|
|
237
238
|
};
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
|
|
241
|
+
async run(context) {
|
|
241
242
|
console.log('run default command at %s', context.argv.baseDir);
|
|
242
243
|
}
|
|
243
244
|
}
|
|
@@ -257,7 +258,7 @@ class RemoteCommand extends Command {
|
|
|
257
258
|
this.load(path.join(__dirname, 'remote'));
|
|
258
259
|
}
|
|
259
260
|
|
|
260
|
-
|
|
261
|
+
async run({ argv }) {
|
|
261
262
|
console.log('run remote command with %j', argv._);
|
|
262
263
|
}
|
|
263
264
|
|
|
@@ -281,7 +282,7 @@ class AddCommand extends Command {
|
|
|
281
282
|
|
|
282
283
|
}
|
|
283
284
|
|
|
284
|
-
|
|
285
|
+
async run({ argv }) {
|
|
285
286
|
console.log('git remote add %s to %s with tags=%s', argv.name, argv.url, argv.tags);
|
|
286
287
|
}
|
|
287
288
|
|
|
@@ -298,7 +299,6 @@ see [remote.js](test/fixtures/my-git/command/remote.js) for more detail.
|
|
|
298
299
|
|
|
299
300
|
```js
|
|
300
301
|
class SleepCommand extends Command {
|
|
301
|
-
|
|
302
302
|
async run() {
|
|
303
303
|
await sleep('1s');
|
|
304
304
|
console.log('sleep 1s');
|
|
@@ -316,7 +316,6 @@ function sleep(ms) {
|
|
|
316
316
|
|
|
317
317
|
see [async-bin](test/fixtures/async-bin) for more detail.
|
|
318
318
|
|
|
319
|
-
|
|
320
319
|
### Bash-Completions
|
|
321
320
|
|
|
322
321
|
```bash
|
|
@@ -329,7 +328,7 @@ $ my-git completion >> ~/.bashrc
|
|
|
329
328
|

|
|
330
329
|
|
|
331
330
|
|
|
332
|
-
## Migrating from v1 to
|
|
331
|
+
## Migrating from v1 to v3
|
|
333
332
|
|
|
334
333
|
### bin
|
|
335
334
|
|
|
@@ -340,7 +339,7 @@ $ my-git completion >> ~/.bashrc
|
|
|
340
339
|
const run = require('common-bin').run;
|
|
341
340
|
run(require('../lib/my_program'));
|
|
342
341
|
|
|
343
|
-
//
|
|
342
|
+
// 3.x
|
|
344
343
|
// require a main Command
|
|
345
344
|
const Command = require('..');
|
|
346
345
|
new Command().start();
|
|
@@ -356,7 +355,7 @@ new Command().start();
|
|
|
356
355
|
// 1.x
|
|
357
356
|
this.addCommand('test', path.join(__dirname, 'test_command.js'));
|
|
358
357
|
|
|
359
|
-
//
|
|
358
|
+
// 3.x
|
|
360
359
|
const Command = require('common-bin');
|
|
361
360
|
const pkg = require('./package.json');
|
|
362
361
|
|
|
@@ -375,7 +374,7 @@ class MainCommand extends Command {
|
|
|
375
374
|
|
|
376
375
|
- `help()` is not use anymore.
|
|
377
376
|
- should provide `name`, `description`, `options`.
|
|
378
|
-
-
|
|
377
|
+
- `async run()` arguments had change to object, recommand to use destructuring style - `{ cwd, env, argv, rawArgv }`
|
|
379
378
|
- `argv` is an object parse by `yargs`, **not `args`.**
|
|
380
379
|
- `rawArgv` is equivalent to old `args`
|
|
381
380
|
|
|
@@ -387,7 +386,7 @@ class TestCommand extends Command {
|
|
|
387
386
|
}
|
|
388
387
|
}
|
|
389
388
|
|
|
390
|
-
//
|
|
389
|
+
// 3.x
|
|
391
390
|
class TestCommand extends Command {
|
|
392
391
|
constructor() {
|
|
393
392
|
super();
|
|
@@ -399,7 +398,7 @@ class TestCommand extends Command {
|
|
|
399
398
|
};
|
|
400
399
|
}
|
|
401
400
|
|
|
402
|
-
|
|
401
|
+
async run({ cwd, env, argv, rawArgv }) {
|
|
403
402
|
console.log('run mocha test at %s with %j', cwd, argv);
|
|
404
403
|
}
|
|
405
404
|
|
|
@@ -425,6 +424,6 @@ class TestCommand extends Command {
|
|
|
425
424
|
| :---: | :---: | :---: | :---: | :---: | :---: |
|
|
426
425
|
[<img src="https://avatars.githubusercontent.com/u/7477670?v=4" width="100px;"/><br/><sub><b>tenpend</b></sub>](https://github.com/tenpend)<br/>|[<img src="https://avatars.githubusercontent.com/u/6399899?v=4" width="100px;"/><br/><sub><b>hacke2</b></sub>](https://github.com/hacke2)<br/>|[<img src="https://avatars.githubusercontent.com/u/11896359?v=4" width="100px;"/><br/><sub><b>liuqipeng417</b></sub>](https://github.com/liuqipeng417)<br/>|[<img src="https://avatars.githubusercontent.com/u/36788851?v=4" width="100px;"/><br/><sub><b>Jarvis2018</b></sub>](https://github.com/Jarvis2018)<br/>
|
|
427
426
|
|
|
428
|
-
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `
|
|
427
|
+
This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Jun 04 2022 00:31:29 GMT+0800`.
|
|
429
428
|
|
|
430
|
-
<!-- GITCONTRIBUTOR_END -->
|
|
429
|
+
<!-- GITCONTRIBUTOR_END -->
|
package/index.d.ts
CHANGED
|
@@ -81,7 +81,7 @@ declare class CommonBin {
|
|
|
81
81
|
* @param {String|Class} target - special file path (must contains ext) or Command Class
|
|
82
82
|
* @example `add('test', path.join(__dirname, 'test_command.js'))`
|
|
83
83
|
*/
|
|
84
|
-
add(name: string, target: string | CommonBin): void;
|
|
84
|
+
add(name: string, target: string | typeof CommonBin): void;
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* alias an existing command
|
package/lib/command.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const debug = require('debug')('common-bin');
|
|
4
|
-
const co = require('co');
|
|
5
4
|
const yargs = require('yargs');
|
|
6
5
|
const parser = require('yargs-parser');
|
|
7
6
|
const helper = require('./helper');
|
|
@@ -9,7 +8,7 @@ const assert = require('assert');
|
|
|
9
8
|
const fs = require('fs');
|
|
10
9
|
const path = require('path');
|
|
11
10
|
const semver = require('semver');
|
|
12
|
-
const
|
|
11
|
+
const { camelCase } = require('change-case');
|
|
13
12
|
const chalk = require('chalk');
|
|
14
13
|
|
|
15
14
|
const DISPATCH = Symbol.for('eb:Command#dispatch');
|
|
@@ -128,16 +127,18 @@ class CommonBin {
|
|
|
128
127
|
/**
|
|
129
128
|
* start point of bin process
|
|
130
129
|
*/
|
|
131
|
-
start() {
|
|
132
|
-
|
|
130
|
+
async start() {
|
|
131
|
+
try {
|
|
133
132
|
// replace `--get-yargs-completions` to our KEY, so yargs will not block our DISPATCH
|
|
134
133
|
const index = this.rawArgv.indexOf('--get-yargs-completions');
|
|
135
134
|
if (index !== -1) {
|
|
136
135
|
// bash will request as `--get-yargs-completions my-git remote add`, so need to remove 2
|
|
137
136
|
this.rawArgv.splice(index, 2, `--AUTO_COMPLETIONS=${this.rawArgv.join(',')}`);
|
|
138
137
|
}
|
|
139
|
-
|
|
140
|
-
}
|
|
138
|
+
await this[DISPATCH]();
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.errorHandler(err);
|
|
141
|
+
}
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
/**
|
|
@@ -146,10 +147,11 @@ class CommonBin {
|
|
|
146
147
|
* @protected
|
|
147
148
|
*/
|
|
148
149
|
errorHandler(err) {
|
|
149
|
-
console.error(
|
|
150
|
-
console.error(chalk.red(
|
|
151
|
-
|
|
152
|
-
debug(
|
|
150
|
+
console.error(err);
|
|
151
|
+
// console.error(chalk.red(`⚠️ ${err.name}: ${err.message}`));
|
|
152
|
+
// console.error(chalk.red('⚠️ Command Error, enable `DEBUG=common-bin` for detail'));
|
|
153
|
+
// debug('args %s', process.argv.slice(3));
|
|
154
|
+
// debug(err.stack);
|
|
153
155
|
process.exit(1);
|
|
154
156
|
}
|
|
155
157
|
|
|
@@ -203,7 +205,7 @@ class CommonBin {
|
|
|
203
205
|
* @param {Array} context.rawArgv - the raw argv, `[ "--baseDir=simple" ]`
|
|
204
206
|
* @private
|
|
205
207
|
*/
|
|
206
|
-
|
|
208
|
+
async [DISPATCH]() {
|
|
207
209
|
// define --help and --version by default
|
|
208
210
|
const _yargs = this.yargs
|
|
209
211
|
// .reset()
|
|
@@ -220,7 +222,7 @@ class CommonBin {
|
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
// get parsed argument without handling helper and version
|
|
223
|
-
const parsed =
|
|
225
|
+
const parsed = await this[PARSE](this.rawArgv);
|
|
224
226
|
const commandName = parsed._[0];
|
|
225
227
|
|
|
226
228
|
if (parsed.version && this.version) {
|
|
@@ -237,7 +239,7 @@ class CommonBin {
|
|
|
237
239
|
debug('[%s] dispatch to subcommand `%s` -> `%s` with %j', this.constructor.name, commandName, Command.name, rawArgv);
|
|
238
240
|
const command = this.getSubCommandInstance(Command, rawArgv);
|
|
239
241
|
this.subCommand = command; // by zhennann
|
|
240
|
-
|
|
242
|
+
await command[DISPATCH]();
|
|
241
243
|
return;
|
|
242
244
|
}
|
|
243
245
|
|
|
@@ -253,12 +255,11 @@ class CommonBin {
|
|
|
253
255
|
if (context.argv.AUTO_COMPLETIONS) {
|
|
254
256
|
// slice to remove `--AUTO_COMPLETIONS=` which we append
|
|
255
257
|
this.yargs.getCompletion(this.rawArgv.slice(1), completions => {
|
|
256
|
-
// console.log('%s', completions)
|
|
257
258
|
completions.forEach(x => console.log(x));
|
|
258
259
|
});
|
|
259
260
|
} else {
|
|
260
261
|
// handle by self
|
|
261
|
-
|
|
262
|
+
await this.helper.callFn(this.run, [ context ], this);
|
|
262
263
|
}
|
|
263
264
|
}
|
|
264
265
|
|
|
@@ -299,7 +300,7 @@ class CommonBin {
|
|
|
299
300
|
if (this.parserOptions.removeCamelCase) {
|
|
300
301
|
for (const key of Object.keys(argv)) {
|
|
301
302
|
if (key.includes('-')) {
|
|
302
|
-
argv[
|
|
303
|
+
argv[camelCase(key)] = undefined;
|
|
303
304
|
}
|
|
304
305
|
}
|
|
305
306
|
}
|
|
@@ -328,7 +329,7 @@ class CommonBin {
|
|
|
328
329
|
// remove from origin argv
|
|
329
330
|
for (const key of Object.keys(execArgvObj)) {
|
|
330
331
|
argv[key] = undefined;
|
|
331
|
-
argv[
|
|
332
|
+
argv[camelCase(key)] = undefined;
|
|
332
333
|
}
|
|
333
334
|
|
|
334
335
|
// exports execArgv
|
package/lib/helper.js
CHANGED
|
@@ -106,7 +106,7 @@ exports.spawn = (cmd, args = [], options = {}) => {
|
|
|
106
106
|
* @param {String} cwd - target directory
|
|
107
107
|
* @return {Promise} err or undefined
|
|
108
108
|
*/
|
|
109
|
-
exports.npmInstall = (npmCli, name, cwd) => {
|
|
109
|
+
exports.npmInstall = async (npmCli, name, cwd) => {
|
|
110
110
|
const options = {
|
|
111
111
|
stdio: 'inherit',
|
|
112
112
|
env: process.env,
|
|
@@ -116,25 +116,25 @@ exports.npmInstall = (npmCli, name, cwd) => {
|
|
|
116
116
|
const args = [ 'i', name ];
|
|
117
117
|
console.log('[common-bin] `%s %s` to %s ...', npmCli, args.join(' '), options.cwd);
|
|
118
118
|
|
|
119
|
-
return exports.spawn(npmCli, args, options);
|
|
119
|
+
return await exports.spawn(npmCli, args, options);
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
/**
|
|
123
123
|
* call fn
|
|
124
124
|
* @function helper#callFn
|
|
125
|
-
* @param {Function} fn - support
|
|
125
|
+
* @param {Function} fn - support async / normal function return promise
|
|
126
126
|
* @param {Array} [args] - fn args
|
|
127
127
|
* @param {Object} [thisArg] - this
|
|
128
128
|
* @return {Object} result
|
|
129
129
|
*/
|
|
130
|
-
exports.callFn =
|
|
130
|
+
exports.callFn = async (fn, args = [], thisArg) => {
|
|
131
131
|
if (!is.function(fn)) return;
|
|
132
132
|
if (is.generatorFunction(fn)) {
|
|
133
|
-
|
|
133
|
+
throw new TypeError('helper.callFn don\'t support generator function');
|
|
134
134
|
}
|
|
135
135
|
const r = fn.apply(thisArg, args);
|
|
136
136
|
if (is.promise(r)) {
|
|
137
|
-
return
|
|
137
|
+
return await r;
|
|
138
138
|
}
|
|
139
139
|
return r;
|
|
140
140
|
};
|
package/package.json
CHANGED
|
@@ -1,33 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhennann/common-bin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Abstraction bin tool",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"change-case": "^3.0.2",
|
|
12
|
-
"co": "^4.6.0",
|
|
13
|
-
"dargs": "^6.0.0",
|
|
14
|
-
"debug": "^4.1.0",
|
|
7
|
+
"chalk": "^4.1.2",
|
|
8
|
+
"change-case": "^4.1.2",
|
|
9
|
+
"dargs": "^7.0.0",
|
|
10
|
+
"debug": "^4.3.4",
|
|
15
11
|
"is-type-of": "^1.2.1",
|
|
16
|
-
"semver": "^
|
|
12
|
+
"semver": "^7.3.7",
|
|
17
13
|
"yargs": "^13.3.0",
|
|
18
14
|
"yargs-parser": "^13.1.2"
|
|
19
15
|
},
|
|
20
16
|
"devDependencies": {
|
|
21
|
-
"
|
|
22
|
-
"coffee": "^5.
|
|
23
|
-
"egg-bin": "^
|
|
24
|
-
"
|
|
25
|
-
"eslint": "^
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"rimraf": "^2.6.2",
|
|
30
|
-
"typescript": "^3.2.2"
|
|
17
|
+
"@types/node": "^18.15.3",
|
|
18
|
+
"coffee": "^5.4.0",
|
|
19
|
+
"egg-bin": "^5.12.2",
|
|
20
|
+
"eslint": "^8.31.0",
|
|
21
|
+
"eslint-config-egg": "^12.1.0",
|
|
22
|
+
"git-contributor": "2",
|
|
23
|
+
"mm": "^3.2.1",
|
|
24
|
+
"typescript": "^4.7.2"
|
|
31
25
|
},
|
|
32
26
|
"repository": {
|
|
33
27
|
"type": "git",
|
|
@@ -38,29 +32,19 @@
|
|
|
38
32
|
"license": "MIT",
|
|
39
33
|
"scripts": {
|
|
40
34
|
"contributor": "git-contributor",
|
|
41
|
-
"autod": "autod",
|
|
42
|
-
"clean": "rimraf coverage",
|
|
43
35
|
"lint": "eslint .",
|
|
44
36
|
"test": "npm run lint -- --fix && npm run test-local",
|
|
45
37
|
"test-local": "egg-bin test",
|
|
46
38
|
"cov": "egg-bin cov",
|
|
47
|
-
"ci": "npm run
|
|
39
|
+
"ci": "npm run lint && egg-bin cov"
|
|
48
40
|
},
|
|
49
41
|
"engines": {
|
|
50
|
-
"node": ">=
|
|
42
|
+
"node": ">= 14.0.0"
|
|
51
43
|
},
|
|
52
44
|
"files": [
|
|
53
45
|
"lib",
|
|
54
46
|
"index.d.ts",
|
|
55
47
|
"index.js"
|
|
56
48
|
],
|
|
57
|
-
"types": "index.d.ts"
|
|
58
|
-
"ci": {
|
|
59
|
-
"version": "8, 10, 12, 14, 16",
|
|
60
|
-
"type": "github",
|
|
61
|
-
"license": {
|
|
62
|
-
"year": "2017",
|
|
63
|
-
"fullname": "node-modules and other contributors"
|
|
64
|
-
}
|
|
65
|
-
}
|
|
49
|
+
"types": "index.d.ts"
|
|
66
50
|
}
|