Sorry, the diff of this file is not supported yet
+42
-6
| 'use strict' | ||
| const onExit = require('signal-exit') | ||
| const yargs = require('yargs') | ||
| const path = require('path') | ||
@@ -14,3 +13,6 @@ const fs = require('fs') | ||
| if (started && !exited) { | ||
| // tested, but exit mechanism can't collect coverage | ||
| /* istanbul ignore next */ | ||
| if (signal) { | ||
| /* istanbul ignore next */ | ||
| console.error('Abnormal exit:', signal) | ||
@@ -29,4 +31,6 @@ } else { | ||
| ? nameMatch.test(pkg.bin) | ||
| : Object.keys(pkg.bin).some(b => nameMatch.test(b) || nameMatch.test(pkg.bin[b])) | ||
| : pkg.bin && Object.keys(pkg.bin).some(b => nameMatch.test(b) || nameMatch.test(pkg.bin[b])) | ||
| if (isInPackage) { | ||
| /* istanbul ignore next */ | ||
| if (global['NO_NOTIFIER']) throw new Error('NO NOTIFIER') | ||
| const updateNotifier = require('update-notifier'); | ||
@@ -38,9 +42,41 @@ updateNotifier({pkg: pkg}).notify() | ||
| let yargs | ||
| let opts | ||
| let argv | ||
| try { | ||
| /* istanbul ignore next */ | ||
| if (global['NO_YARGS']) throw new Error('NO YARGS') | ||
| yargs = require('yargs') | ||
| opts = yargs.argv | ||
| argv = opts._ | ||
| } catch (_) { | ||
| argv = process.argv.slice(2) | ||
| opts = {_: argv} | ||
| const noYargs = () => { | ||
| throw new Error('Argument parsing is not available (could not find yargs), to install run: npm i yargs') | ||
| } | ||
| // only missing on v4, which has incomplete coverage anyway | ||
| /* istanbul ignore next */ | ||
| yargs = global.Proxy && new global.Proxy({}, { | ||
| getPrototypeOf: noYargs, | ||
| setPrototypeOf: noYargs, | ||
| isExtensible: noYargs, | ||
| preventExtensions: noYargs, | ||
| getOwnPropertyDescriptor: noYargs, | ||
| defineProperty: noYargs, | ||
| has: noYargs, | ||
| get: noYargs, | ||
| set: noYargs, | ||
| deleteProperty: noYargs, | ||
| ownKeys: noYargs, | ||
| apply: noYargs, | ||
| construct: noYargs | ||
| }) | ||
| } | ||
| setImmediate(() => { | ||
| const argv = yargs.argv | ||
| started = true | ||
| try { | ||
| const appPromise = entry.apply(null, [argv].concat(argv._)) | ||
| const appPromise = entry.apply(null, [opts].concat(argv)) | ||
| if (!appPromise || !appPromise.then) { | ||
| return onError(new Error('Error: Application entry point' + (entry.name ? ` (${entry.name})` : '') + ' did not return a promise.')) | ||
| return onError(new Error('Application entry point' + (entry.name ? ` (${entry.name})` : '') + ' did not return a promise.')) | ||
| } | ||
@@ -56,3 +92,3 @@ appPromise.then(() => exited = true, onError) | ||
| } else if (err) { | ||
| console.error(err && err.stack ? err.stack : err) | ||
| console.error((err && err.stack) ? err.stack : err) | ||
| } | ||
@@ -59,0 +95,0 @@ process.exit(1) |
+11
-6
| { | ||
| "name": "@iarna/cli", | ||
| "version": "1.2.0", | ||
| "version": "2.0.0", | ||
| "description": "Some simple CLI scaffolding for promise returning applications.", | ||
| "main": "app.js", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| "test": "tap --100 test/scenarios.js" | ||
| }, | ||
@@ -13,5 +13,3 @@ "keywords": [], | ||
| "dependencies": { | ||
| "signal-exit": "^3.0.2", | ||
| "update-notifier": "^2.2.0", | ||
| "yargs": "^8.0.2" | ||
| "signal-exit": "^3.0.2" | ||
| }, | ||
@@ -21,3 +19,10 @@ "files": [ | ||
| ], | ||
| "devDependencies": {}, | ||
| "devDependencies": { | ||
| "@perl/qr": "^1.2.0", | ||
| "@perl/qx": "^1.0.2", | ||
| "glob": "^7.1.2", | ||
| "tap": "^12.0.1", | ||
| "update-notifier": "^2.2.0", | ||
| "yargs": "^8.0.2" | ||
| }, | ||
| "repository": { | ||
@@ -24,0 +29,0 @@ "type": "git", |
+62
-13
@@ -5,7 +5,33 @@ # @iarna/cli | ||
|  | ||
| ## EXAMPLE | ||
| ### Without Yargs | ||
| If you don't have yargs installed as a dependency then you get arguments | ||
| split out but no option parsing: | ||
| `example.js` | ||
| ```js | ||
| require('@iarna/cli')(main) | ||
| const util = require('util'); | ||
| const sleep = util.promisify(setTimeout); | ||
| // opts will only contain the _ var, for compatibility with yargs | ||
| async function main (opts, arg1, arg2, arg3) { | ||
| console.log('Got:', arg1, arg2, arg3) | ||
| await sleep(40) | ||
| } | ||
| ``` | ||
| ### With Yargs | ||
| If you do have yargs installed as a dependency you can customize it further | ||
| by chaining off the require in the usual yargsish way. | ||
| `example.js` | ||
| ```js | ||
| require('@iarna/cli')(main) | ||
| .boolean('silent') | ||
@@ -19,2 +45,5 @@ .boolean('exit') | ||
| const util = require('util'); | ||
| const sleep = util.promisify(setTimeout); | ||
| function main (opts, arg1, arg2, arg3) { | ||
@@ -27,4 +56,7 @@ if (!opts.silent) console.error('Starting up!') | ||
| if (opts.code50) return Promise.reject(50) | ||
| return new Promise(resolve => setTimeout(resolve, 10000)) | ||
| return sleep(10000) | ||
| } | ||
| // alternatively use: | ||
| // function main (opts, ...args) { | ||
| ``` | ||
@@ -70,17 +102,19 @@ | ||
| * `yargs` - The wrapper around the main function returns a yargs object, so | ||
| you can configure it as usual. The `argv` object is passed in as the | ||
| first argument of your entry point function. The rest of your positional | ||
| arguments are passed in as the remaining function arguments. | ||
| * _exit without resolving warnings_ - If your program finishes without | ||
| resolving its promises (like if it crashes hard or you process.exit, or you just don't resolve the promise ) then | ||
| we warn about that. | ||
| * `update-notifier` - A default update notifier is setup for your app so | ||
| users will learn about new versions when you publish them. Your app needs to | ||
| have a name, version and bin entry in its `package.json`. (The bin entry | ||
| needs to have the script using `@iarna/cli` in it for the update notifier | ||
| to trigger.) | ||
| * If your entry point function rejects then that's reported with a stack | ||
| trace (if the rejected value has `.stack`) else with the rejected value | ||
| and your process will exit with an error code. | ||
| * If you add `yargs` as a dependency then it will be taken advantage of. | ||
| The wrapper around the main function returns a yargs object, so you can | ||
| configure it as usual. The `argv` object is passed in as the first | ||
| argument of your entry point function. The rest of your positional | ||
| arguments are passed in as the remaining function arguments. | ||
| * If you add `update-notifier` as a dependency then it will be taken | ||
| advantage of. A default update notifier is setup for your app so users | ||
| will learn about new versions when you publish them. Your app needs to | ||
| have a name, version and bin entry in its `package.json`. (The bin entry | ||
| needs to have the script using `@iarna/cli` in it for the update notifier | ||
| to trigger.) | ||
@@ -94,5 +128,9 @@ ## WHAT ITS NOT | ||
| It's designed to be only be as heavy as it needs to be. It only has one | ||
| direct dependency, but it can provide enhanced functionality if you depend on | ||
| `yargs` or `update-notifier`. | ||
| ## USAGE | ||
| ### require('@iarna/cli')(entryPointFunction) → yargs | ||
| ### require('@iarna/cli')(entryPointFunction) → [yargs] | ||
@@ -104,2 +142,7 @@ The module itself exports a function that you need to call with the name of | ||
| The return value from the call is, if you have `yargs` installed, a `yargs` | ||
| object you can use to configure what options your script takes. If you | ||
| don't have yargs installed then it's a proxy that throws if you try to do | ||
| anything with it. | ||
| Your entry point function can be named anything, but it needs to return a | ||
@@ -110,3 +153,9 @@ promise and it takes arguments like this: | ||
| The first `opts` argument is `yargs.argv` and the additional arguments are | ||
| from `argv._`, so `arg1 === argv._[0]`, `arg2 === argv._[1]` and so on. | ||
| If you have `yargs` installed then the `opts` argument is `yargs.argv` | ||
| and the additional arguments are from `argv._`, so `arg1 === argv._[0]`, | ||
| `arg2 === argv._[1]` and so on. | ||
| If you don't have `yargs` installed then `opts` argument is an object with | ||
| an `_` property containing all arguments, for compatibility with the `yargs` | ||
| mode. As with that mode `arg1 === argv._[0]`, `arg2 === argv._[1]` and so | ||
| on. |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
14909
113.66%1
-66.67%5
25%93
63.16%0
-100%155
46.23%6
Infinity%- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed