some fixes + nesting works, still need to think and simplify...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-06-16 15:48:43 +03:00
parent 643665be5a
commit 679437a822
3 changed files with 85 additions and 21 deletions

58
argv.js
View File

@ -288,6 +288,11 @@ object.Constructor('Parser', {
// Handler API... // Handler API...
// XXX should these be .getOptions(..) / .getCommands(..) ??? // XXX should these be .getOptions(..) / .getCommands(..) ???
// Format:
// [
// [<keys>, <arg>, <doc>, <handler>],
// ...
// ]
options: function(...prefix){ options: function(...prefix){
var that = this var that = this
prefix = prefix.length == 0 ? prefix = prefix.length == 0 ?
@ -298,7 +303,6 @@ object.Constructor('Parser', {
var handlers = {} var handlers = {}
object.deepKeys(that, Parser.prototype) object.deepKeys(that, Parser.prototype)
.forEach(function(opt){ .forEach(function(opt){
// XXX
if(!opt.startsWith(prefix)){ if(!opt.startsWith(prefix)){
return } return }
var [k, h] = that.getHandler(opt) var [k, h] = that.getHandler(opt)
@ -306,7 +310,20 @@ object.Constructor('Parser', {
handlers[k][0].push(opt) handlers[k][0].push(opt)
: (handlers[k] = [[opt], h.arg, h.doc || k.slice(1), h]) }) : (handlers[k] = [[opt], h.arg, h.doc || k.slice(1), h]) })
return Object.values(handlers) }) return Object.values(handlers) })
.flat(1) }, .flat(1)
.map(function(e, i){ return [e, i] })
.sort(function([a, ai], [b, bi]){
a = a[3].priority
b = b[3].priority
return a != null && b != null ?
b - a
// positive priority above order, negative below...
: (a > 0 || b < 0) ?
-1
: (b < 0 || a > 0) ?
1
: ai - bi })
.map(function([e, _]){ return e }) },
commands: function(){ commands: function(){
return this.options(this.commandPrefix) }, return this.options(this.commandPrefix) },
@ -360,6 +377,7 @@ object.Constructor('Parser', {
'-h': '-help', '-h': '-help',
'-help': { '-help': {
doc: 'print this message and exit.', doc: 'print this message and exit.',
priority: 99,
// XXX argv is first for uniformity with .__call__(..) -- need // XXX argv is first for uniformity with .__call__(..) -- need
// the two to be interchangeable... // the two to be interchangeable...
// ...an alternative would keep it last, but this feels more fragile... // ...an alternative would keep it last, but this feels more fragile...
@ -432,11 +450,34 @@ object.Constructor('Parser', {
process.exit(1) }, process.exit(1) },
__call__: function(_, argv){ // XXX need to unify this with handler as much as possible to make
// parsers nestable....
// there are differences that can't be avoided:
// - argv/rest -- argv includes 2 extra args:
// - interpreter
// - script
// ...these should be either avoided or "inherited"
__call__: function(context, argv){
// nested command handler...
// XXX the condition is a bit too strong...
if(context instanceof Parser){
var rest = this.rest = argv.slice()
this.script = this.scriptName =
context.scriptName +' '+ arguments[2]
this.argv = [context.scriptName, this.scriptName, ...argv]
// root parser...
} else {
var rest = this.rest = argv.slice() var rest = this.rest = argv.slice()
this.argv = argv.slice() this.argv = argv.slice()
// XXX revise this...
// - when run from node -- [<node>, <script>, ...]
// - when run from electron -- [<electron>, ...]
// require('electron').remove.process.argv
this.interpreter = rest.shift()
this.script = rest[0] this.script = rest[0]
this.scriptName = rest.shift().split(/[\\\/]/).pop() this.scriptName = rest.shift().split(/[\\\/]/).pop()
}
var opt_pattern = this.optionPattern var opt_pattern = this.optionPattern
@ -462,10 +503,9 @@ object.Constructor('Parser', {
handler handler
: handler.handler) : handler.handler)
.call(this, .call(this,
// pass value... argv,
...(handler.arg ? [value] : []),
arg, arg,
argv) ...(handler.arg ? [value] : []))
continue } continue }
// other... // other...
other.push(arg) } other.push(arg) }
@ -475,10 +515,8 @@ object.Constructor('Parser', {
Object.assign(this, spec) Object.assign(this, spec)
// check for alias loops... // check for alias loops...
this.__pre_check__ this.initCheck
&& this.__getoptions__( && this.options(this.optionPrefix, this.commandPrefix)
this.__opt_pattern__ || module.OPTION_PATTERN,
this.__cmd_pattern__ || module.COMMAND_PATTERN)
}, },
}) })

View File

@ -24,6 +24,6 @@
"homepage": "https://github.com/flynx/argv.js#readme", "homepage": "https://github.com/flynx/argv.js#readme",
"dependencies": { "dependencies": {
"colors": "^1.4.0", "colors": "^1.4.0",
"ig-object": "^5.0.12" "ig-object": "^5.0.13"
} }
} }

32
test.js
View File

@ -17,7 +17,9 @@ var argv = require('./argv')
//--------------------------------------------------------------------- //---------------------------------------------------------------------
var p = argv.Parser({ var p =
module.p =
argv.Parser({
'@help': '-help', '@help': '-help',
'-v': '-verbose', '-v': '-verbose',
@ -28,13 +30,27 @@ var p = argv.Parser({
'-c': '@command', '-c': '@command',
'@cmd': '@command', '@cmd': '@command',
'@command': function(){ '@command': {
priority: -50,
handler: function(){
console.log('>>> COMMAND:', ...arguments) console.log('>>> COMMAND:', ...arguments)
return 'command' return 'command'
}, },
},
// XXX this for some reason breaks...
//'@test': argv.Parser({
//}),
'@nested': argv.Parser({
doc: 'nested parser.',
}),
}) })
/*
console.log(' ->', p(['test', '--verbose', 'a', 'b', 'c'])) console.log(' ->', p(['test', '--verbose', 'a', 'b', 'c']))
console.log(' ->', p(['test', '-c', 'a', 'b', 'c'])) console.log(' ->', p(['test', '-c', 'a', 'b', 'c']))
@ -43,8 +59,18 @@ console.log(' ->', p(['test', 'command', 'a', 'b', 'c']))
console.log('---') console.log('---')
p(['test', '-h'])
p(['test', 'nested', '-h'])
p(['test', '-h'])
//*/
if(typeof(__filename) != 'undefined'
&& __filename == (require.main || {}).filename){
p(process.argv)
}
/********************************************************************** /**********************************************************************