mirror of
https://github.com/flynx/argv.js.git
synced 2025-10-28 10:20:09 +00:00
added experimental chaining, still has issues...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
33e4afce60
commit
191790edeb
26
ADVANCED.md
26
ADVANCED.md
@ -54,6 +54,7 @@ For basics see [README.md](./README.md)
|
||||
- [`<parser>.error(..)`](#parsererror-1)
|
||||
- [`<parser>.off(..)`](#parseroff)
|
||||
- [`<parser>(..)`](#parser-1)
|
||||
- [`Parser.chain(..)` (EXPERIMENTAL)](#parserchain-experimental)
|
||||
- [Advanced parser API](#advanced-parser-api)
|
||||
- [`<parser>.print(..)` / `<parser>.printError(..)`](#parserprint--parserprinterror)
|
||||
- [`<parser>.handlerDefault(..)`](#parserhandlerdefault)
|
||||
@ -763,6 +764,31 @@ be ignored, otherwise the whole list is processed as if `<main>` was
|
||||
its head.
|
||||
|
||||
|
||||
### `Parser.chain(..)` (EXPERIMENTAL)
|
||||
|
||||
Chain several parsers for staggering option/command processing.
|
||||
```
|
||||
Parser.chain(<spec>, <spec>, ..)
|
||||
-> <parser>
|
||||
```
|
||||
|
||||
This creates a chain of parsers, each processing only the arguments it defines
|
||||
and passes the rest to the next in chain. This is useful for defining arguments
|
||||
that need to be processed out of order and before anything else.
|
||||
|
||||
This is similar to chaining parsers via `.then(..)` but with additional setup:
|
||||
- all parsers except the last will have:
|
||||
- `.splitOptions` set to `false`
|
||||
- `"-help"` set to `undefined` enabling `-help` pass-through
|
||||
- `"-*"` and `"@*"` set to `undefined` enabling arguments pass-through
|
||||
- the last parser will have all the options from the other parsers merged into
|
||||
it for complete docs/`-help`
|
||||
|
||||
|
||||
XXX the resulting `<parsed>` object will only contain data from the last parser,
|
||||
this may change in the future.
|
||||
|
||||
|
||||
|
||||
## Advanced parser API
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ This code is an evolution of that parser.
|
||||
- `-version` – print version
|
||||
- `-quiet` – suppress printing
|
||||
- `-` – stop argument processing
|
||||
- Extensible
|
||||
- Extensible and self-applicable
|
||||
|
||||
|
||||
### Planned
|
||||
|
||||
59
argv.js
59
argv.js
@ -319,6 +319,44 @@ object.Constructor('Parser', {
|
||||
toggle: function(v, cur){ return !cur },
|
||||
},
|
||||
|
||||
// XXX this does not merge the parse results... (???)
|
||||
// XXX EXPERIMENTAL...
|
||||
chain: function(...parsers){
|
||||
var Parser = this
|
||||
var [post, ...pre] = parsers.reverse()
|
||||
pre.reverse()
|
||||
|
||||
// prepare the final parser for merged doc...
|
||||
// XXX object.deepKeys(..) ???
|
||||
var final = Parser(Object.assign({},
|
||||
// set attribute order...
|
||||
// NOTE: this is here to set the attribute order according
|
||||
// to priority...
|
||||
...pre,
|
||||
// set the correct values...
|
||||
post,
|
||||
...pre))
|
||||
|
||||
return pre
|
||||
// setup the chain for arg pass-through...
|
||||
.map(function(e){
|
||||
// XXX object.deepKeys(..) ???
|
||||
return Parser(Object.assign({},
|
||||
e,
|
||||
{
|
||||
splitOptions: false,
|
||||
'-help': undefined,
|
||||
'-*': undefined,
|
||||
'@*': undefined,
|
||||
})) })
|
||||
.concat([final])
|
||||
// chain...
|
||||
.reduce(function(res, cur){
|
||||
return res ?
|
||||
// NOTE: need to call .then(..) on each of the parsers,
|
||||
// so we return cur to be next...
|
||||
(res.then(cur), cur)
|
||||
: cur }, null) },
|
||||
}, {
|
||||
// config...
|
||||
//
|
||||
@ -1096,8 +1134,10 @@ object.Constructor('Parser', {
|
||||
return res }
|
||||
// NOTE: if successful this needs to modify the arg, thus it
|
||||
// returns both the new first arg and the handler...
|
||||
// XXX if no handler is found this should return the original
|
||||
// input arg...
|
||||
// NOTE: if the first letter is a fail the whole arg will get
|
||||
// reported...
|
||||
// XXX do we need to report the specific fail or the whole
|
||||
// unsplit arg??? (see below)
|
||||
var splitArgs = function(arg, rest){
|
||||
var [arg, value] = arg.split(/=/)
|
||||
// skip single letter unknown or '--' options...
|
||||
@ -1111,9 +1151,18 @@ object.Constructor('Parser', {
|
||||
// push the value to the last arg...
|
||||
value !== undefined
|
||||
&& r.push(r.pop() +'='+ value)
|
||||
var h = parsed.handler(a)[1]
|
||||
// XXX do we need to report the specific fail or the whole
|
||||
// unsplit arg???
|
||||
// check the rest of the args...
|
||||
//if(h && r.reduce(function(r, a){
|
||||
// return r && parsed.handler(a)[1] }, true)){
|
||||
if(h){
|
||||
// push new options back to option "stack"...
|
||||
rest.splice(0, 0, ...r)
|
||||
return [ a, parsed.handler(a)[1] ] }
|
||||
return [ a, h ] }
|
||||
// no handler found -> return undefined
|
||||
return [ arg, undefined ] }
|
||||
|
||||
try{
|
||||
// parse/interpret the arguments and call handlers...
|
||||
@ -1139,6 +1188,7 @@ object.Constructor('Parser', {
|
||||
: parsed.isCommand(arg) ?
|
||||
['cmd', COMMAND_PREFIX +'*']
|
||||
: ['unhandled']
|
||||
// no handler is found...
|
||||
if(type == 'unhandled'){
|
||||
unhandled.push(arg)
|
||||
continue }
|
||||
@ -1156,9 +1206,6 @@ object.Constructor('Parser', {
|
||||
// dynamic or error...
|
||||
|| parsed.handler(dfl)[1]
|
||||
// no handler found and '-*' or '@*' not defined...
|
||||
// XXX if nether the whole arg nor it split are found
|
||||
// we need to push the original to unhandled...
|
||||
// ...or is setting .splitOptions to false enough???
|
||||
if(handler == null){
|
||||
unhandled.push(arg)
|
||||
continue }
|
||||
|
||||
@ -52,8 +52,34 @@ argv.Parser({
|
||||
'any other options']},
|
||||
}))
|
||||
|
||||
|
||||
var parser2 =
|
||||
exports.parser2 =
|
||||
argv.Parser.chain({
|
||||
'-a': {
|
||||
doc: [
|
||||
'high priority option',
|
||||
'this will get processed before',
|
||||
'any other options'],
|
||||
handler: function(){
|
||||
console.log('### high priority option') }},
|
||||
},{
|
||||
'-b': {
|
||||
doc: 'medium priority option',
|
||||
handler: function(){
|
||||
console.log('### normal priority option') }},
|
||||
},{
|
||||
'-c': {
|
||||
doc: 'normal priority option',
|
||||
handler: function(){
|
||||
console.log('### normal priority option') }},
|
||||
})
|
||||
|
||||
|
||||
|
||||
// run the parser...
|
||||
__filename == (require.main || {}).filename
|
||||
&& parser(process.argv)
|
||||
&& parser2()
|
||||
|
||||
|
||||
// vim:set ts=4 sw=4 spell :
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-argv",
|
||||
"version": "2.14.0",
|
||||
"version": "2.15.0",
|
||||
"description": "simple argv parser",
|
||||
"main": "argv.js",
|
||||
"scripts": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user