added unknown option delegation up (EXPERIMENTAL)

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2023-01-31 16:37:37 +03:00
parent 72103ea846
commit cfaa901611
4 changed files with 37 additions and 8 deletions

View File

@ -17,9 +17,6 @@ This code is an evolution of that parser.
- Simple / well documented - Simple / well documented
- Supports both the _option_ (a-la `ls`) and _command_ (a-la `git`) paradigms - Supports both the _option_ (a-la `ls`) and _command_ (a-la `git`) paradigms
- Nestable
parsers can be nested as option/command handlers defining independent
nested contexts
- Option expansion - Option expansion
`-abc` expands to `-a -b -c` if `-abc` is not defined `-abc` expands to `-a -b -c` if `-abc` is not defined
- Option/command value assignment - Option/command value assignment
@ -37,6 +34,12 @@ This code is an evolution of that parser.
- `-version` &ndash; print version - `-version` &ndash; print version
- `-quiet` &ndash; suppress printing - `-quiet` &ndash; suppress printing
- `-` &ndash; stop argument processing - `-` &ndash; stop argument processing
- Nestable
parsers can be nested as option/command handlers defining independent
nested contexts
- Option delegation
options not handled by the current nested parser will be automatically
delegated back to parent parser
- Extensible and self-applicable - Extensible and self-applicable
@ -454,6 +457,10 @@ external command.
When a nested parser is started it will consume subsequent arguments until it When a nested parser is started it will consume subsequent arguments until it
exits, then the parent parser will pick up where it left. exits, then the parent parser will pick up where it left.
When a nested parser encounters an unknown option/command it will stop and
the option will be delegated to the parent parser. This can be disabled by
setting `<parser>.delegateUnknownToParent` to `false`.
Externally it is treated in exactly the same way as a normal _function_ handler, Externally it is treated in exactly the same way as a normal _function_ handler,
essentially, the parent parser does not know the difference between the two. essentially, the parent parser does not know the difference between the two.

27
argv.js
View File

@ -52,8 +52,9 @@ var COMMAND_PREFIX = '@'
//--------------------------------------------------------------------- //---------------------------------------------------------------------
module.STOP = object.STOP module.STOP =
|| {doc: 'Stop option processing, triggers .stop(..) handlers'} object.STOP
|| {doc: 'Stop option processing, triggers .stop(..) handlers'}
module.THEN = module.THEN =
{doc: 'Break option processing, triggers .then(..) handlers'} {doc: 'Break option processing, triggers .then(..) handlers'}
@ -1071,12 +1072,30 @@ object.Constructor('Parser', {
// //
// NOTE: to explicitly handle '-*' option or '*' command define handlers // NOTE: to explicitly handle '-*' option or '*' command define handlers
// for them under '-\\*' and '@\\*' respectively. // for them under '-\\*' and '@\\*' respectively.
// Handle unknown otions...
// - deligate to parent if .delegateUnknownToParent is true
// - thrwo error
delegateUnknownToParent: true,
'-*': { '-*': {
doc: false, doc: false,
//section_doc: ..., //section_doc: ...,
handler: function(_, key){ handler: function(_, key, value){
// delegate to parent...
if(this.delegateUnknownToParent
&& this.parent){
this.parent.rest.unshift(
value === undefined ?
key
: key+'='+value)
return module.THEN }
// error...
throw module.ParserError( throw module.ParserError(
`Unknown ${key.startsWith('-') ? 'option:' : 'command:'} $ARG`) } }, `Unknown ${
key.startsWith('-') ?
'option:'
: 'command:'
} $ARG`) } },
'@*': '-*', '@*': '-*',

View File

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

View File

@ -38,6 +38,9 @@ test.Setups({
// NOTE: this will also load .bare, .opts and .lang // NOTE: this will also load .bare, .opts and .lang
basic: function(assert){ basic: function(assert){
return argv.Parser({ return argv.Parser({
examples: [
'$SCRIPTNAME moo foo boo'
],
// disable exit on error... // disable exit on error...
handleErrorExit: false, handleErrorExit: false,