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>(...)
|
||||
-> <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,
|
||||
- everything is run in the _context_ of the `<parsed>` object so any
|
||||
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
|
||||
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
|
||||
to indicate that the option/command is present in the command-line.
|
||||
If option is given but no value is set, `undefined` is assigned to option
|
||||
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
|
||||
unless `.collect` is set (see `-push` example below).
|
||||
Note that repeating a basic option/command will overwrite the previous occurrences'
|
||||
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))
|
||||
|
||||
```javascript
|
||||
'-bool': {
|
||||
doc: 'if given, set .bool to true' },
|
||||
'-flag': {
|
||||
doc: 'if given, set .flag' },
|
||||
|
||||
|
||||
// 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.
|
||||
arg: '| required_option_given',
|
||||
|
||||
default: true,
|
||||
|
||||
// NOTE: by default required options/commands are sorted above normal
|
||||
// options but bellow -help/-version/-quiet/...
|
||||
// (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,
|
||||
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
|
||||
@ -494,7 +506,7 @@ Options:
|
||||
(required)
|
||||
--default=VALUE - option with default value
|
||||
(default: some value)
|
||||
--bool - if given set .bool to true
|
||||
--flag - if given set .flag
|
||||
--value=X - set .x to X
|
||||
(required 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.
|
||||
// (see '-?' for a usage example)
|
||||
// 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...
|
||||
[key, handler] =
|
||||
;[key, handler] =
|
||||
typeof(handler) == typeof('str') ?
|
||||
this.handler(handler)
|
||||
: [key, handler]
|
||||
@ -748,7 +748,8 @@ object.Constructor('Parser', {
|
||||
'-q': '-quiet',
|
||||
'-quiet': {
|
||||
priority: 99,
|
||||
doc: 'quiet mode', },
|
||||
doc: 'quiet mode',
|
||||
default: true, },
|
||||
|
||||
|
||||
// Stop argument processing...
|
||||
@ -865,11 +866,8 @@ object.Constructor('Parser', {
|
||||
// get the final key...
|
||||
|| this.handler(key)[0].slice(1)
|
||||
// if value not given set true and handle...
|
||||
//this[key] = arguments.length < 3 ?
|
||||
value = arguments.length < 3 ?
|
||||
(this.handleArgumentValue ?
|
||||
this.handleArgumentValue(handler, true)
|
||||
: true)
|
||||
value = this.handleArgumentValue ?
|
||||
this.handleArgumentValue(handler, value)
|
||||
: value
|
||||
|
||||
this[attr] = this._handleValue(handler,
|
||||
@ -981,18 +979,22 @@ object.Constructor('Parser', {
|
||||
parsed.error(reason, arg, rest)
|
||||
parsed.handleErrorExit
|
||||
&& parsed.handleErrorExit(arg, reason) }
|
||||
var runHandler = function(handler, arg, rest){
|
||||
var runHandler = function(handler, arg, rest, mode){
|
||||
var [arg, value] = arg instanceof Array ?
|
||||
arg
|
||||
: arg.split(/=/)
|
||||
var env = handler.env
|
||||
&& handler.env.replace(/^\$/, '')
|
||||
// get value...
|
||||
value = value == null ?
|
||||
((parsed.hasArgument(handler)
|
||||
&& rest.length > 0
|
||||
&& !opt_pattern.test(rest[0])) ?
|
||||
rest.shift()
|
||||
: (typeof(process) != 'undefined' && handler.env) ?
|
||||
process.env[handler.env.replace(/^\$/, '')]
|
||||
: (typeof(process) != 'undefined'
|
||||
&& env
|
||||
&& env in process.env) ?
|
||||
process.env[env]
|
||||
: value)
|
||||
: value
|
||||
value = value == null ?
|
||||
@ -1007,6 +1009,11 @@ object.Constructor('Parser', {
|
||||
if(handler.valueRequired && value == null){
|
||||
throw module.ParserValueError('Value missing: ${ arg }=?') }
|
||||
|
||||
// do not call the handler if value is implicitly undefined...
|
||||
if(value === undefined
|
||||
&& mode == 'implicit'){
|
||||
return }
|
||||
|
||||
// run handler...
|
||||
try {
|
||||
var res = parsed.handle(handler, rest, arg, value)
|
||||
@ -1056,6 +1063,7 @@ object.Constructor('Parser', {
|
||||
while(rest.length > 0 || (values.size || values.length) > 0){
|
||||
// explicitly passed options...
|
||||
if(rest.length > 0){
|
||||
var mode = 'explicit'
|
||||
var arg = rest.shift()
|
||||
// non-string stuff in arg list...
|
||||
if(typeof(arg) != typeof('str')){
|
||||
@ -1094,13 +1102,14 @@ object.Constructor('Parser', {
|
||||
|
||||
// implicit options -- with .env and or .default set...
|
||||
} else {
|
||||
var mode = 'implicit'
|
||||
values = values instanceof Map ?
|
||||
[...values]
|
||||
: values
|
||||
var [handler, arg] = values.shift() }
|
||||
|
||||
|
||||
var res = runHandler(handler, arg, rest)
|
||||
var res = runHandler(handler, arg, rest, mode)
|
||||
|
||||
// handle stop conditions...
|
||||
if(res === module.STOP
|
||||
|
||||
@ -16,8 +16,8 @@ argv.Parser({
|
||||
footer: 'Written by: $AUTHOR\nVersion: $VERSION / License: $LICENSE',
|
||||
|
||||
|
||||
'-bool': {
|
||||
doc: 'if given, set .bool to true' },
|
||||
'-flag': {
|
||||
doc: 'if given, set .bool' },
|
||||
|
||||
|
||||
// option with a value...
|
||||
@ -48,6 +48,8 @@ argv.Parser({
|
||||
// NOTE: of no attr is specified in arg option name is used.
|
||||
arg: '| required_option_given',
|
||||
|
||||
default: true,
|
||||
|
||||
// NOTE: by default required options/commands are sorted above normal
|
||||
// options but bellow -help/-version/-quiet/...
|
||||
// (by default at priority 80)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-argv",
|
||||
"version": "2.10.4",
|
||||
"version": "2.11.0",
|
||||
"description": "simple argv parser",
|
||||
"main": "argv.js",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user