mirror of
https://github.com/flynx/argv.js.git
synced 2025-10-28 18:30:07 +00:00
reworked handling of implicit options...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6c2df284b2
commit
ed23022e83
30
README.md
30
README.md
@ -98,7 +98,8 @@ Parser(..) -> <parser>(..) -> <parsed>
|
|||||||
<parser>(...)
|
<parser>(...)
|
||||||
-> <parsed>
|
-> <parsed>
|
||||||
```
|
```
|
||||||
- option handlers (defined in `<spec>`) are called while parsing,
|
- arguments are handled in order of occurrence,
|
||||||
|
- argument handlers (defined in `<spec>`) are called while parsing,
|
||||||
- then/stop/error `<callback>`'s are called after the `<parser>` is done,
|
- then/stop/error `<callback>`'s are called after the `<parser>` is done,
|
||||||
- everything is run in the _context_ of the `<parsed>` object so any
|
- everything is run in the _context_ of the `<parsed>` object so any
|
||||||
data set on it is accessible after parsing is done for further
|
data set on it is accessible after parsing is done for further
|
||||||
@ -218,18 +219,22 @@ These, if encountered, simply assign a value to an attribute on the parsed objec
|
|||||||
Any option/command can be passed a value, either explicitly (e.g. `-opt=123`) or
|
Any option/command can be passed a value, either explicitly (e.g. `-opt=123`) or
|
||||||
implicitly by first setting `.arg` (see examples below) and and then passing `-opt 123`.
|
implicitly by first setting `.arg` (see examples below) and and then passing `-opt 123`.
|
||||||
|
|
||||||
If no value is given `true` is assigned to option attribute on the parsed object
|
If option is given but no value is set, `undefined` is assigned to option
|
||||||
to indicate that the option/command is present in the command-line.
|
attribute on the parsed object to indicate that the option/command is present
|
||||||
|
in the command-line.
|
||||||
|
Note that values can be set on the command-line as well as via
|
||||||
|
[`<option>.env`](./ADVANCED.md#optionenv) and/or
|
||||||
|
[`<option>.default`](./ADVANCED.md#optiondefault) see examples below.
|
||||||
|
|
||||||
Note that repeating a basic option/command will overwrite the previous value
|
Note that repeating a basic option/command will overwrite the previous occurrences'
|
||||||
unless `.collect` is set (see `-push` example below).
|
value unless `.collect` is set (see `-push` example below).
|
||||||
|
|
||||||
Note that in general case option order in the command-line is not critical,
|
Note that in the general case option order in the command-line is not critical,
|
||||||
but option context can matter (see: [Active options/commands](#active-optionscommands) and [Nested parsers](#nested-parsers))
|
but option context can matter (see: [Active options/commands](#active-optionscommands) and [Nested parsers](#nested-parsers))
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
'-bool': {
|
'-flag': {
|
||||||
doc: 'if given, set .bool to true' },
|
doc: 'if given, set .flag' },
|
||||||
|
|
||||||
|
|
||||||
// option with a value...
|
// option with a value...
|
||||||
@ -263,6 +268,8 @@ but option context can matter (see: [Active options/commands](#active-optionscom
|
|||||||
// NOTE: of no attr is specified in arg option name is used.
|
// NOTE: of no attr is specified in arg option name is used.
|
||||||
arg: '| required_option_given',
|
arg: '| required_option_given',
|
||||||
|
|
||||||
|
default: true,
|
||||||
|
|
||||||
// NOTE: by default required options/commands are sorted above normal
|
// NOTE: by default required options/commands are sorted above normal
|
||||||
// options but bellow -help/-version/-quiet/...
|
// options but bellow -help/-version/-quiet/...
|
||||||
// (by default at priority 80)
|
// (by default at priority 80)
|
||||||
@ -355,6 +362,11 @@ And for quick-n-dirty hacking stuff together, a shorthand (_not for production u
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `.handler(..)` will get called if the option is present in the command-line,
|
||||||
|
if either `.default` is not `undefined` or if `.env` and its environment
|
||||||
|
variable are defined, or any combination of the above. And vice-versa, if none
|
||||||
|
of the above conditions are met the `.handler(..)` will not be called.
|
||||||
|
|
||||||
Option's `.handler(..)` only sees the `args` that follow it in the command line,
|
Option's `.handler(..)` only sees the `args` that follow it in the command line,
|
||||||
thus anything it may expect/get from the arguments must follow it (in the manner
|
thus anything it may expect/get from the arguments must follow it (in the manner
|
||||||
it expects), `argv.js` poses no restrictions on full or partial manual handling
|
it expects), `argv.js` poses no restrictions on full or partial manual handling
|
||||||
@ -494,7 +506,7 @@ Options:
|
|||||||
(required)
|
(required)
|
||||||
--default=VALUE - option with default value
|
--default=VALUE - option with default value
|
||||||
(default: some value)
|
(default: some value)
|
||||||
--bool - if given set .bool to true
|
--flag - if given set .flag
|
||||||
--value=X - set .x to X
|
--value=X - set .x to X
|
||||||
(required value)
|
(required value)
|
||||||
-i=INT - pass an integer value
|
-i=INT - pass an integer value
|
||||||
|
|||||||
33
argv.js
33
argv.js
@ -463,9 +463,9 @@ object.Constructor('Parser', {
|
|||||||
// delegate option processing to a different option.
|
// delegate option processing to a different option.
|
||||||
// (see '-?' for a usage example)
|
// (see '-?' for a usage example)
|
||||||
// NOTE: this will not handle anything outside of handler call
|
// NOTE: this will not handle anything outside of handler call
|
||||||
handle: function(handler, rest, key, value){
|
handle: function(handler, rest, key, value, mode){
|
||||||
// got flag as handler...
|
// got flag as handler...
|
||||||
[key, handler] =
|
;[key, handler] =
|
||||||
typeof(handler) == typeof('str') ?
|
typeof(handler) == typeof('str') ?
|
||||||
this.handler(handler)
|
this.handler(handler)
|
||||||
: [key, handler]
|
: [key, handler]
|
||||||
@ -748,7 +748,8 @@ object.Constructor('Parser', {
|
|||||||
'-q': '-quiet',
|
'-q': '-quiet',
|
||||||
'-quiet': {
|
'-quiet': {
|
||||||
priority: 99,
|
priority: 99,
|
||||||
doc: 'quiet mode', },
|
doc: 'quiet mode',
|
||||||
|
default: true, },
|
||||||
|
|
||||||
|
|
||||||
// Stop argument processing...
|
// Stop argument processing...
|
||||||
@ -865,11 +866,8 @@ object.Constructor('Parser', {
|
|||||||
// get the final key...
|
// get the final key...
|
||||||
|| this.handler(key)[0].slice(1)
|
|| this.handler(key)[0].slice(1)
|
||||||
// if value not given set true and handle...
|
// if value not given set true and handle...
|
||||||
//this[key] = arguments.length < 3 ?
|
value = this.handleArgumentValue ?
|
||||||
value = arguments.length < 3 ?
|
this.handleArgumentValue(handler, value)
|
||||||
(this.handleArgumentValue ?
|
|
||||||
this.handleArgumentValue(handler, true)
|
|
||||||
: true)
|
|
||||||
: value
|
: value
|
||||||
|
|
||||||
this[attr] = this._handleValue(handler,
|
this[attr] = this._handleValue(handler,
|
||||||
@ -981,18 +979,22 @@ object.Constructor('Parser', {
|
|||||||
parsed.error(reason, arg, rest)
|
parsed.error(reason, arg, rest)
|
||||||
parsed.handleErrorExit
|
parsed.handleErrorExit
|
||||||
&& parsed.handleErrorExit(arg, reason) }
|
&& parsed.handleErrorExit(arg, reason) }
|
||||||
var runHandler = function(handler, arg, rest){
|
var runHandler = function(handler, arg, rest, mode){
|
||||||
var [arg, value] = arg instanceof Array ?
|
var [arg, value] = arg instanceof Array ?
|
||||||
arg
|
arg
|
||||||
: arg.split(/=/)
|
: arg.split(/=/)
|
||||||
|
var env = handler.env
|
||||||
|
&& handler.env.replace(/^\$/, '')
|
||||||
// get value...
|
// get value...
|
||||||
value = value == null ?
|
value = value == null ?
|
||||||
((parsed.hasArgument(handler)
|
((parsed.hasArgument(handler)
|
||||||
&& rest.length > 0
|
&& rest.length > 0
|
||||||
&& !opt_pattern.test(rest[0])) ?
|
&& !opt_pattern.test(rest[0])) ?
|
||||||
rest.shift()
|
rest.shift()
|
||||||
: (typeof(process) != 'undefined' && handler.env) ?
|
: (typeof(process) != 'undefined'
|
||||||
process.env[handler.env.replace(/^\$/, '')]
|
&& env
|
||||||
|
&& env in process.env) ?
|
||||||
|
process.env[env]
|
||||||
: value)
|
: value)
|
||||||
: value
|
: value
|
||||||
value = value == null ?
|
value = value == null ?
|
||||||
@ -1007,6 +1009,11 @@ object.Constructor('Parser', {
|
|||||||
if(handler.valueRequired && value == null){
|
if(handler.valueRequired && value == null){
|
||||||
throw module.ParserValueError('Value missing: ${ arg }=?') }
|
throw module.ParserValueError('Value missing: ${ arg }=?') }
|
||||||
|
|
||||||
|
// do not call the handler if value is implicitly undefined...
|
||||||
|
if(value === undefined
|
||||||
|
&& mode == 'implicit'){
|
||||||
|
return }
|
||||||
|
|
||||||
// run handler...
|
// run handler...
|
||||||
try {
|
try {
|
||||||
var res = parsed.handle(handler, rest, arg, value)
|
var res = parsed.handle(handler, rest, arg, value)
|
||||||
@ -1056,6 +1063,7 @@ object.Constructor('Parser', {
|
|||||||
while(rest.length > 0 || (values.size || values.length) > 0){
|
while(rest.length > 0 || (values.size || values.length) > 0){
|
||||||
// explicitly passed options...
|
// explicitly passed options...
|
||||||
if(rest.length > 0){
|
if(rest.length > 0){
|
||||||
|
var mode = 'explicit'
|
||||||
var arg = rest.shift()
|
var arg = rest.shift()
|
||||||
// non-string stuff in arg list...
|
// non-string stuff in arg list...
|
||||||
if(typeof(arg) != typeof('str')){
|
if(typeof(arg) != typeof('str')){
|
||||||
@ -1094,13 +1102,14 @@ object.Constructor('Parser', {
|
|||||||
|
|
||||||
// implicit options -- with .env and or .default set...
|
// implicit options -- with .env and or .default set...
|
||||||
} else {
|
} else {
|
||||||
|
var mode = 'implicit'
|
||||||
values = values instanceof Map ?
|
values = values instanceof Map ?
|
||||||
[...values]
|
[...values]
|
||||||
: values
|
: values
|
||||||
var [handler, arg] = values.shift() }
|
var [handler, arg] = values.shift() }
|
||||||
|
|
||||||
|
|
||||||
var res = runHandler(handler, arg, rest)
|
var res = runHandler(handler, arg, rest, mode)
|
||||||
|
|
||||||
// handle stop conditions...
|
// handle stop conditions...
|
||||||
if(res === module.STOP
|
if(res === module.STOP
|
||||||
|
|||||||
@ -16,8 +16,8 @@ argv.Parser({
|
|||||||
footer: 'Written by: $AUTHOR\nVersion: $VERSION / License: $LICENSE',
|
footer: 'Written by: $AUTHOR\nVersion: $VERSION / License: $LICENSE',
|
||||||
|
|
||||||
|
|
||||||
'-bool': {
|
'-flag': {
|
||||||
doc: 'if given, set .bool to true' },
|
doc: 'if given, set .bool' },
|
||||||
|
|
||||||
|
|
||||||
// option with a value...
|
// option with a value...
|
||||||
@ -48,6 +48,8 @@ argv.Parser({
|
|||||||
// NOTE: of no attr is specified in arg option name is used.
|
// NOTE: of no attr is specified in arg option name is used.
|
||||||
arg: '| required_option_given',
|
arg: '| required_option_given',
|
||||||
|
|
||||||
|
default: true,
|
||||||
|
|
||||||
// NOTE: by default required options/commands are sorted above normal
|
// NOTE: by default required options/commands are sorted above normal
|
||||||
// options but bellow -help/-version/-quiet/...
|
// options but bellow -help/-version/-quiet/...
|
||||||
// (by default at priority 80)
|
// (by default at priority 80)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ig-argv",
|
"name": "ig-argv",
|
||||||
"version": "2.10.4",
|
"version": "2.11.0",
|
||||||
"description": "simple argv parser",
|
"description": "simple argv parser",
|
||||||
"main": "argv.js",
|
"main": "argv.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
9
test.js
9
test.js
@ -89,6 +89,15 @@ argv.Parser({
|
|||||||
'-sh': {
|
'-sh': {
|
||||||
doc: 'short option', },
|
doc: 'short option', },
|
||||||
|
|
||||||
|
'-env': {
|
||||||
|
doc: 'env value',
|
||||||
|
arg: 'VALUE | env_value',
|
||||||
|
env: 'VALUE',
|
||||||
|
|
||||||
|
//default: 5,
|
||||||
|
handler: function(args, key, value){ console.log('GOT ENV:', value) },
|
||||||
|
},
|
||||||
|
|
||||||
'-type-error': {
|
'-type-error': {
|
||||||
doc: 'throw a type error',
|
doc: 'throw a type error',
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user