added real pattern args...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-12-10 21:51:34 +03:00
parent 9d09eb220c
commit e3ffd4bc5f
5 changed files with 72 additions and 5 deletions

View File

@ -62,6 +62,7 @@ This code is an evolution of that parser.
- [Basic options](#basic-options)
- [Commands](#commands)
- [Active options/commands](#active-optionscommands)
- [Pattern options](#pattern-options)
- [Nested parsers](#nested-parsers)
- [Stopping](#stopping)
- [Error reporting](#error-reporting)
@ -335,6 +336,7 @@ For more info on available `.type` and `.collect` handlers see:
respectively.
### Commands
The only difference between an _option_ and a _command_ is the prefix (`"-"` vs. `"@"`)
@ -383,6 +385,26 @@ it expects), `argv.js` poses no restrictions on full or partial manual handling
of arguments by options/commands.
### Pattern options
Pattern option/command keys enable partial input key matching.
```javascript
'-prefix-*': {
doc: 'Pattern option',
handler: function(rest, key){
// ...
} },
```
The above code will match any _unhandled_ input option starting with
`-prefix-`/`--prefix-` and push the explicitly `false` value back to the option
queue.
A pattern option/command is any option with a key containing `"*"`.
### Nested parsers
An options/command handler can also be a full fledged parser.
@ -551,6 +573,7 @@ Options:
-c - command
--active - basic active option
-s, --shorthand-active - shorthand-active
--prefix-* - Pattern option
--then - then
--stop - stop
--error - error

38
argv.js
View File

@ -429,10 +429,11 @@ object.Constructor('Parser', {
prefix = prefix.length == 0 ?
[OPTION_PREFIX]
: prefix
var attrs = object.deepKeys(that, Parser.prototype)
return prefix
.map(function(prefix){
var handlers = {}
object.deepKeys(that, Parser.prototype)
attrs
.forEach(function(opt){
if(!opt.startsWith(prefix)){
return }
@ -496,6 +497,28 @@ object.Constructor('Parser', {
requiredArguments: function(){
return this.requiredOptions('allArguments') },
//
// .patternArguments()
// -> list
//
// Get list of pattern args that key matches...
// .patternArguments(key)
// -> list
//
// NOTE: list is sorted by option length...
// NOTE: pattern->pattern aliases are not currently supported...
// NOTE: output is of the same format as .options(..)
// NOTE: when changing this revise a corresponding section in .handler(..)
patternArguments: function(key){
return this.allArguments()
.filter(function([[opt]]){
return opt.includes('*')
&& (key == null
|| (new RegExp(`^${ opt.split('*').join('.*') }$`)).test(key)) })
// sort longest first...
.sort(function(a, b){
return b[0][0].length - a[0][0].length }) },
// Get handler...
//
// .handler(key)
@ -523,6 +546,19 @@ object.Constructor('Parser', {
// report loop...
'loop', [...seen, key]] }
seen.add(key) }
// check pattern options...
// NOTE: we are not using .patternArguments(..) because .options(..)
// used there uses .handler(..) and this breaks things...
if(!(key in this) && key != '-*'){
key = object.deepKeys(this, Parser.prototype)
.filter(function(opt){
return opt.includes('*')
&& (key == null
|| (new RegExp(`^${ opt.split('*').join('.*') }$`))
.test(key)) })
.sort(function(a, b){
return b[0][0].length - a[0][0].length })[0]
|| key }
return [key, this[key],
// report dead-end if this[key] is undefined...
...(this[key] ?

View File

@ -120,6 +120,12 @@ argv.Parser({
// ...
},
'-prefix-*': {
doc: 'Pattern option',
handler: function(rest, key){
// ...
},
},
'@nested': argv.Parser({
// ...

View File

@ -1,6 +1,6 @@
{
"name": "ig-argv",
"version": "2.15.7",
"version": "2.16.0",
"description": "simple argv parser",
"main": "argv.js",
"scripts": {

View File

@ -28,14 +28,14 @@ var setups =
test.Setups({
bare: function(){
return require('./examples/bare').parser },
options: function(){
opts: function(){
return require('./examples/options').parser },
lang: function(){
return require('./examples/lang').parser },
chain: function(){
return require('./examples/chain').parser },
// NOTE: this will also load .bare, .options and .lang
// NOTE: this will also load .bare, .opts and .lang
basic: function(assert){
return argv.Parser({
// disable exit on error...
@ -175,13 +175,15 @@ test.Setups({
'@bare': setups.bare(assert),
'@opts': setups.options(assert),
'@opts': setups.opts(assert),
'@lang': setups.lang(assert),
'@chain': setups.chain(assert),
// collision test...
// NOTE: values of these will shadow the API...
// XXX need to either warn the user of this or think of a
// way to avoid this...
'@options': {},
'-handler': {},
})