From cfaa901611ad3bab0788469b3dfa8133319dc526 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Tue, 31 Jan 2023 16:37:37 +0300 Subject: [PATCH] added unknown option delegation up (EXPERIMENTAL) Signed-off-by: Alex A. Naanou --- README.md | 13 ++++++++++--- argv.js | 27 +++++++++++++++++++++++---- package.json | 2 +- test.js | 3 +++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6991fd4..c374f07 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,6 @@ This code is an evolution of that parser. - Simple / well documented - 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 `-abc` expands to `-a -b -c` if `-abc` is not defined - Option/command value assignment @@ -37,6 +34,12 @@ This code is an evolution of that parser. - `-version` – print version - `-quiet` – suppress printing - `-` – 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 @@ -454,6 +457,10 @@ external command. When a nested parser is started it will consume subsequent arguments until it 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 `.delegateUnknownToParent` to `false`. + 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. diff --git a/argv.js b/argv.js index 47c2d36..0acb98d 100644 --- a/argv.js +++ b/argv.js @@ -52,8 +52,9 @@ var COMMAND_PREFIX = '@' //--------------------------------------------------------------------- -module.STOP = object.STOP - || {doc: 'Stop option processing, triggers .stop(..) handlers'} +module.STOP = + object.STOP + || {doc: 'Stop option processing, triggers .stop(..) handlers'} module.THEN = {doc: 'Break option processing, triggers .then(..) handlers'} @@ -1071,12 +1072,30 @@ object.Constructor('Parser', { // // NOTE: to explicitly handle '-*' option or '*' command define handlers // for them under '-\\*' and '@\\*' respectively. + + // Handle unknown otions... + // - deligate to parent if .delegateUnknownToParent is true + // - thrwo error + delegateUnknownToParent: true, '-*': { doc: false, //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( - `Unknown ${key.startsWith('-') ? 'option:' : 'command:'} $ARG`) } }, + `Unknown ${ + key.startsWith('-') ? + 'option:' + : 'command:' + } $ARG`) } }, '@*': '-*', diff --git a/package.json b/package.json index 39d802b..d8294ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-argv", - "version": "2.16.10", + "version": "2.17.0", "description": "simple argv parser", "main": "argv.js", "scripts": { diff --git a/test.js b/test.js index 9fbc412..fbeb5bd 100755 --- a/test.js +++ b/test.js @@ -38,6 +38,9 @@ test.Setups({ // NOTE: this will also load .bare, .opts and .lang basic: function(assert){ return argv.Parser({ + examples: [ + '$SCRIPTNAME moo foo boo' + ], // disable exit on error... handleErrorExit: false,