more work on argv parser, almost ready to split out...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-06-13 19:08:19 +03:00
parent c684fc0f08
commit c700ec3812

85
test.js
View File

@ -187,7 +187,9 @@ var ArgvParser = function(spec){
return [opts.join(' | -') +' '+ (arg || ''), doc] })), return [opts.join(' | -') +' '+ (arg || ''), doc] })),
// commands... // commands...
...(((x = spec.__getcommands__()) && x.length > 0) ? ...(((x = spec.__getcommands__()) && x.length > 0) ?
['', 'Commands:', ...x] ['', 'Commands:',
...x.map(function([cmd, _, doc]){
return [cmd.join(' | '), doc] })]
: []), : []),
// examples... // examples...
...(this.spec.__examples__ ? ...(this.spec.__examples__ ?
@ -248,24 +250,32 @@ var ArgvParser = function(spec){
process.exit(1) }, process.exit(1) },
// these are run in the context of spec... // these are run in the context of spec...
__getoptions__: function(pattern){ __getoptions__: function(...pattern){
var that = this var that = this
var handlers = {} pattern = pattern.length == 0 ?
pattern = pattern [this.__opt_pattern__
|| this.__opt_pattern__ || module.OPTION_PATTERN]
|| module.OPTION_PATTERN : pattern
Object.keys(this) return pattern
.forEach(function(opt){ .map(function(pattern){
// skip special methods... var handlers = {}
if(/^__.*__$/.test(opt) Object.keys(that)
&& !pattern.test(opt)){ .forEach(function(opt){
return } // skip special methods...
var [k, h] = that.__gethandler__(opt) if(/^__.*__$/.test(opt)
handlers[k] ? || !pattern.test(opt)){
handlers[k][0].push(opt) return }
: (handlers[k] = [[opt], h.arg, h.doc || k, h]) }) var [k, h] = that.__gethandler__(opt)
return Object.values(handlers) }, handlers[k] ?
// XXX get all instances of ArgvParser in spec... handlers[k][0].push(opt)
: (handlers[k] = [[opt], h.arg, h.doc || k, h]) })
return Object.values(handlers) })
.flat(1) },
__iscommand__: function(str){
return (this.__cmd_pattern__
|| module.COMMAND_PATTERN)
.test(str)
&& str in this },
__getcommands__: function(){ __getcommands__: function(){
return this.__getoptions__( return this.__getoptions__(
this.__cmd_pattern__ this.__cmd_pattern__
@ -286,13 +296,16 @@ var ArgvParser = function(spec){
return [key, this[key]] }, return [key, this[key]] },
}, spec) }, spec)
// sanity check -- this will detect argument loops... // sanity check -- this will detect argument loops for builtin opts
if(!!spec.__pre_check__){ // and commands...
spec.__getoptions__() spec.__pre_check__
spec.__getcommands__()} && spec.__getoptions__(
spec.__opt_pattern__ || module.OPTION_PATTERN,
spec.__cmd_pattern__ || module.COMMAND_PATTERN)
return function(argv){ return function(argv){
var pattern = /^--?[a-zA-Z-]*$/ var opt_pattern = spec.__opt_pattern__
|| module.OPTION_PATTERN
argv = argv.slice() argv = argv.slice()
var context = { var context = {
spec: spec, spec: spec,
@ -307,12 +320,18 @@ var ArgvParser = function(spec){
var other = [] var other = []
while(argv.length > 0){ while(argv.length > 0){
var arg = argv.shift() var arg = argv.shift()
// options... var type = opt_pattern.test(arg) ?
if(pattern.test(arg)){ 'opt'
: spec.__iscommand__(arg) ?
'cmd'
: 'other'
// options / commands...
if(type != 'other'){
// get handler...
var handler = spec.__gethandler__(arg).pop() var handler = spec.__gethandler__(arg).pop()
|| spec.__unknown__ || spec.__unknown__
// get option value... // get option value...
var value = (handler.arg && !pattern.test(argv[0])) ? var value = (handler.arg && !opt_pattern.test(argv[0])) ?
argv.shift() argv.shift()
: undefined : undefined
// run handler... // run handler...
@ -325,6 +344,7 @@ var ArgvParser = function(spec){
arg, arg,
argv) argv)
continue } continue }
// other...
other.push(arg) } other.push(arg) }
return other } } return other } }
@ -1104,6 +1124,19 @@ if(typeof(__filename) != 'undefined'
doc: 'verbose mode (defaults to: $VERBOSE).', doc: 'verbose mode (defaults to: $VERBOSE).',
handler: function(){ handler: function(){
module.VERBOSE = true }}, module.VERBOSE = true }},
// XXX commands...
'-foo': 'moo',
'moo': 'moue',
'moue': Object.assign(
function(){
console.log('MOO!!!!!!')
process.exit() },
{
doc: 'test command...'
}),
// XXX need to make this nestable...
'nested': ArgvParser({ }),
})(process.argv) })(process.argv)
// run the tests... // run the tests...