Comparing version 1.0.2 to 2.0.0
194
index.js
@@ -1,78 +0,43 @@ | ||
const push = Array.prototype.push | ||
const SHORTSPLIT = /$|[!-@\[-`{-~]/ | ||
const SHORTSPLIT = /$|[!-@\[-`{-~].*/g | ||
const EMPTY = [] | ||
module.exports = function(args, opts) { | ||
opts = opts || {} | ||
return parse( | ||
args, | ||
aliases(opts.alias), | ||
defaults(opts.default, opts.alias), | ||
opts.unknown, | ||
{ _: [] } | ||
) | ||
function array(any) { | ||
return Array.isArray(any) ? any : [any] | ||
} | ||
function parse(args, aliases, defaults, unknown, out) { | ||
for (var i = 0, j = 0, len = args.length, _ = out._; i < len; i++) { | ||
var arg = args[i] | ||
function aliases(aliases) { | ||
var out = {} | ||
if ("--" === arg) { | ||
push.apply(_, args.slice(i + 1)) | ||
break | ||
} else if ("-" === arg[0]) { | ||
if ("-" === arg[1]) { | ||
var end = arg.indexOf("=") | ||
if (0 <= end) { | ||
set(arg.slice(2, end), arg.slice(end + 1), out, aliases, unknown) | ||
} else { | ||
if ("n" === arg[2] && "o" === arg[3] && "-" === arg[4]) { | ||
set(arg.slice(5), false, out, aliases, unknown) | ||
} else { | ||
set( | ||
arg.slice(2), | ||
(j = i + 1) === len || "-" === args[j][0] || args[(i = j)], | ||
out, | ||
aliases, | ||
unknown | ||
) | ||
} | ||
} | ||
} else { | ||
var end = arg.slice(2).search(SHORTSPLIT) + 2 | ||
var value = end === arg.length | ||
? (j = i + 1) === len || "-" === args[j][0] || args[(i = j)] | ||
: arg.slice(end) | ||
for (var key in aliases) { | ||
var alias = (out[key] = array(aliases[key])) | ||
for (j = 1; j < end; ) { | ||
set(arg[j], ++j !== end || value, out, aliases, unknown) | ||
for (var i = 0, len = alias.length; i < len; i++) { | ||
var curr = (out[alias[i]] = [key]) | ||
for (var j = 0; j < len; j++) { | ||
if (i !== j) { | ||
curr.push(alias[j]) | ||
} | ||
} | ||
} else { | ||
_.push(arg) | ||
} | ||
} | ||
for (var key in defaults) { | ||
if (undefined === out[key]) { | ||
out[key] = defaults[key] | ||
} | ||
} | ||
return out | ||
} | ||
function aliases(aliases) { | ||
function booleans(aliases, booleans) { | ||
var out = {} | ||
for (var key in aliases) { | ||
var alias = (out[key] = toArray(aliases[key])) | ||
if (booleans !== undefined) { | ||
for (var i = 0, len = booleans.length; i < len; i++) { | ||
var key = booleans[i] | ||
var alias = aliases[key] | ||
for (var i = 0, len = alias.length; i < len; i++) { | ||
var name = alias[i] | ||
out[name] = [key] | ||
out[key] = true | ||
for (var j = 0; j < len; j++) { | ||
var next = alias[j] | ||
if (next !== name) { | ||
out[name].push(next) | ||
if (alias === undefined) { | ||
aliases[key] = EMPTY | ||
} else { | ||
for (var j = 0, end = alias.length; j < end; j++) { | ||
out[alias[j]] = true | ||
} | ||
@@ -86,23 +51,17 @@ } | ||
function defaults(defaults, aliases) { | ||
if (undefined !== defaults) { | ||
for (var key in aliases) { | ||
var value = defaults[key] | ||
var alias = toArray(aliases[key]) | ||
function defaults(aliases, defaults) { | ||
var out = {} | ||
if (undefined !== value) { | ||
for (var i = 0, len = alias.length; i < len; i++) { | ||
defaults[alias[i]] = value | ||
} | ||
for (var key in defaults) { | ||
var value = defaults[key] | ||
var alias = aliases[key] | ||
if (out[key] === undefined) { | ||
out[key] = value | ||
if (alias === undefined) { | ||
aliases[key] = EMPTY | ||
} else { | ||
for (var i = 0, len = alias.length; i < len; i++) { | ||
if (undefined !== (value = defaults[alias[i]])) { | ||
defaults[key] = value | ||
for (var j = 0; j < len; j++) { | ||
if (i !== j) { | ||
defaults[alias[j]] = value | ||
} | ||
} | ||
} | ||
out[alias[i]] = value | ||
} | ||
@@ -112,12 +71,13 @@ } | ||
} | ||
return defaults | ||
return out | ||
} | ||
function set(key, value, out, aliases, unknown) { | ||
function set(out, key, value, aliases, unknown) { | ||
var curr = out[key] | ||
var alias = aliases[key] | ||
var hasAlias = undefined !== alias | ||
var known = alias !== undefined | ||
if (hasAlias || undefined === unknown || unknown(key) !== false) { | ||
if (undefined === curr) { | ||
if (known || unknown === undefined || false !== unknown(key)) { | ||
if (curr === undefined) { | ||
out[key] = value | ||
@@ -132,3 +92,3 @@ } else { | ||
if (hasAlias) { | ||
if (known) { | ||
for (var i = 0, len = alias.length; i < len; ) { | ||
@@ -141,4 +101,66 @@ out[alias[i++]] = out[key] | ||
function toArray(any) { | ||
return Array.isArray(any) ? any : [any] | ||
module.exports = function(argv, opts) { | ||
var unknown = (opts = opts || {}).unknown | ||
var alias = aliases(opts.alias) | ||
var values = defaults(alias, opts.default) | ||
var bools = booleans(alias, opts.boolean) | ||
var out = { _: [] } | ||
for (var i = 0, j = 0, len = argv.length, _ = out._; i < len; i++) { | ||
var arg = argv[i] | ||
if (arg === "--") { | ||
while (++i < len) { | ||
_.push(argv[i]) | ||
} | ||
} else if (arg === "-" || arg[0] !== "-") { | ||
_.push(arg) | ||
} else { | ||
if (arg[1] === "-") { | ||
var end = arg.indexOf("=", 2) | ||
if (0 <= end) { | ||
set(out, arg.slice(2, end), arg.slice(end + 1), alias, unknown) | ||
} else { | ||
if ("n" === arg[2] && "o" === arg[3] && "-" === arg[4]) { | ||
set(out, arg.slice(5), false, alias, unknown) | ||
} else { | ||
var key = arg.slice(2) | ||
set( | ||
out, | ||
key, | ||
len === (j = i + 1) || | ||
argv[j][0] === "-" || | ||
bools[key] !== undefined || | ||
argv[(i = j)], | ||
alias, | ||
unknown | ||
) | ||
} | ||
} | ||
} else { | ||
SHORTSPLIT.lastIndex = 2 | ||
var match = SHORTSPLIT.exec(arg) | ||
var end = match.index | ||
var value = | ||
match[0] || | ||
len === (j = i + 1) || | ||
argv[j][0] === "-" || | ||
bools[arg[end - 1]] !== undefined || | ||
argv[(i = j)] | ||
for (j = 1; j < end; ) { | ||
set(out, arg[j], ++j !== end || value, alias, unknown) | ||
} | ||
} | ||
} | ||
} | ||
for (var key in values) { | ||
if (out[key] === undefined) { | ||
out[key] = values[key] | ||
} | ||
} | ||
return out | ||
} |
{ | ||
"name": "getopts", | ||
"description": "Node.js CLI options parser.", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"main": "index.js", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
142
README.md
# Getopts | ||
[![Travis CI](https://img.shields.io/travis/getopts/getopts/master.svg)](https://travis-ci.org/getopts/getopts) | ||
[![Codecov](https://img.shields.io/codecov/c/github/getopts/getopts/master.svg)](https://codecov.io/gh/getopts/getopts) | ||
[![Travis CI](https://img.shields.io/travis/JorgeBucaran/getopts/master.svg)](https://travis-ci.org/JorgeBucaran/getopts) | ||
[![Codecov](https://img.shields.io/codecov/c/github/JorgeBucaran/getopts/master.svg)](https://codecov.io/gh/JorgeBucaran/getopts) | ||
[![npm](https://img.shields.io/npm/v/getopts.svg)](https://www.npmjs.org/package/getopts) | ||
@@ -8,5 +8,5 @@ | ||
* **Swift**: Getopts is 10 to 1000 times faster than the alternatives. See [benchmarks](./bench/README.md) for details. | ||
* **Swift**: Getopts is 10 to 20 times faster than the alternatives. See the [benchmarks](./bench/README.md). | ||
* **Familiar**: Getopts works similarly to other CLI parsers like [mri](https://github.com/lukeed/mri), [yargs](https://github.com/yargs/yargs) and [minimist](https://github.com/substack/minimist). | ||
* **Predictable**: Getopts is designed according to the [Utility Syntax Guidelines](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html). | ||
* **Standard**: Getopts is designed according to the [Utility Syntax Guidelines](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html). | ||
@@ -23,96 +23,46 @@ ## Installation | ||
Use Getopts to parse the arguments passed into your program. | ||
Use getopts to parse the arguments passed into your program from the command line. | ||
```console | ||
$ example/demo --jet --mode=turbo -xfv12 -- game over | ||
``` | ||
<pre> | ||
$ <a href="./example/demo">example/demo</a> --super=sonic -jb9000 -- game over | ||
</pre> | ||
And create an object that you can use to lookup options and values. | ||
```js | ||
const deepEqual = require("assert").deepEqual | ||
const getopts = require("getopts") | ||
const args = process.argv.slice(2) | ||
deepEqual(getopts(args), { | ||
_: ["game", "over"], | ||
jet: true, | ||
mode: "turbo", | ||
x: true, | ||
f: true, | ||
v: "12" | ||
const options = getopts(process.argv.slice(2), { | ||
alias: { | ||
s: "super", | ||
b: "blitz" | ||
}, | ||
default: { | ||
turbo: true | ||
} | ||
}) | ||
``` | ||
Create option aliases. | ||
Getopts expects an array of arguments and options object (optional) and returns an object where you can look up the argument keys and their values. | ||
```js | ||
deepEqual( | ||
getopts(args, { | ||
alias: { | ||
j: "jet", | ||
m: "mode", | ||
v: "viper" | ||
} | ||
}), | ||
{ | ||
_: ["game", "over"], | ||
jet: true, | ||
j: true, | ||
mode: "turbo", | ||
m: "turbo", | ||
x: true, | ||
f: true, | ||
v: "12", | ||
viper: "12" | ||
} | ||
) | ||
``` | ||
Populate missing options with default values. | ||
```js | ||
deepEqual( | ||
getopts(args, { | ||
default: { | ||
bolt: true, | ||
hyper: 9000 | ||
} | ||
}), | ||
{ | ||
_: ["game", "over"], | ||
jet: true, | ||
mode: "turbo", | ||
z: "12", | ||
bolt: true, | ||
hyper: 9000 | ||
} | ||
) | ||
{ | ||
_: ["game", "over"], | ||
j: true, | ||
s: "sonic", | ||
b: "9000", | ||
super: "sonic", | ||
blitz: "9000", | ||
turbo: true | ||
} | ||
``` | ||
Identify options without an alias. | ||
## API | ||
```js | ||
getopts(args, { | ||
alias: { | ||
j: "jet", | ||
m: "mode", | ||
v: "viper" | ||
}, | ||
unknown(option) { | ||
throw new Error(`Unknown option: ${option}.`) // => Unknown option: x. | ||
} | ||
}) | ||
``` | ||
### getopts(argv, options) | ||
#### argv | ||
## API | ||
An array of arguments to parse. See [`process.argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv). | ||
### getopts(args, options) | ||
#### args | ||
Arguments that begin with one or two dashes are called options or flags. Options may have one or more [aliases](#optsalias). The underscore key stores operands. Operands include non-options, the single dash `-` and all the arguments after `--`. | ||
An array of arguments to parse. Use [`process.argv.slice(2)`](https://nodejs.org/docs/latest/api/process.html#process_process_argv). | ||
#### options.alias | ||
An object of option aliases. An alias can be a string or an array of aliases. | ||
An object of option aliases. An alias can be a string or an array of strings. | ||
@@ -122,7 +72,17 @@ ```js | ||
alias: { | ||
b: ["B", "boost"] | ||
b: ["B", "turbo"] | ||
} | ||
}) //=> { _:[], b:true, B:true, boost:true } | ||
}) //=> { _:[], b:true, B:true, turbo:true } | ||
``` | ||
#### options.boolean | ||
An array of options that should be parsed as booleans. | ||
```js | ||
getopts(["-b", 1], { | ||
boolean: ["b"] | ||
}) //=> { _:[1], b:true } | ||
``` | ||
#### options.default | ||
@@ -135,5 +95,5 @@ | ||
default: { | ||
super: 9000 | ||
turbo: true | ||
} | ||
}) //=> { _:[], b:true, super:9000 } | ||
}) //=> { _:[], b:true, turbo:true } | ||
``` | ||
@@ -143,8 +103,8 @@ | ||
A function we run for every option without an alias. Return `false` to dismiss the option. | ||
A function that runs for every unknown option. Return `false` to dismiss the option. | ||
```js | ||
getopts(["-xfvz"], { | ||
unknown: option => option === "z" | ||
}) // => { _: [], z:true } | ||
getopts(["-abc"], { | ||
unknown: option => option === "a" | ||
}) // => { _:[], a:true } | ||
``` | ||
@@ -155,3 +115,1 @@ | ||
Getopts is MIT licensed. See [LICENSE](LICENSE.md). | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8026
136
110