mirror of
https://github.com/flynx/argv.js.git
synced 2025-10-29 18:50:09 +00:00
reworked type handlers and value collectors + docs...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
3c00ffcaf8
commit
d3762f4f9c
14
README.md
14
README.md
@ -398,8 +398,13 @@ occurrences of the option and write the result to `<key>`.
|
|||||||
Supported collection modes:
|
Supported collection modes:
|
||||||
- `"list"` – group values into an `Array` object
|
- `"list"` – group values into an `Array` object
|
||||||
- `"set"` – group values into a `Set` object
|
- `"set"` – group values into a `Set` object
|
||||||
- `"string"` – concatenate values into a string
|
- `"string"` – concatenate values into a string.
|
||||||
- `"toggle"` – toggle option value (bool)
|
This also supports an optional separator, for example `"string|\t"` will
|
||||||
|
collect values into a string joining them with a tab (i.e. `"\t"`).
|
||||||
|
Default separator is: `" "`
|
||||||
|
- `"toggle"` – toggle option value (bool).
|
||||||
|
Note that the actual value assigned to an option is ignored here and can
|
||||||
|
be omitted.
|
||||||
|
|
||||||
Type handlers are defined in `Parser.valueCollectors` or can be overwritten
|
Type handlers are defined in `Parser.valueCollectors` or can be overwritten
|
||||||
by `<spec>.valueCollectors`.
|
by `<spec>.valueCollectors`.
|
||||||
@ -407,10 +412,7 @@ by `<spec>.valueCollectors`.
|
|||||||
`<option>.collect` can be used in conjunction with `<option>.type` to both
|
`<option>.collect` can be used in conjunction with `<option>.type` to both
|
||||||
convert and collect values.
|
convert and collect values.
|
||||||
|
|
||||||
If not set, each subsequent option repetition will overwrite the value.
|
If not set, each subsequent option will overwrite the previously set value.
|
||||||
|
|
||||||
If `"toggle"` is set the actual value assigned to an option is ignored
|
|
||||||
and can be omitted.
|
|
||||||
|
|
||||||
|
|
||||||
#### `<option>.env`
|
#### `<option>.env`
|
||||||
|
|||||||
148
argv.js
148
argv.js
@ -128,6 +128,8 @@ function(name, pre, post){
|
|||||||
//
|
//
|
||||||
// type: 'int',
|
// type: 'int',
|
||||||
//
|
//
|
||||||
|
// collect: 'string|, ',
|
||||||
|
//
|
||||||
// env: 'VALUE',
|
// env: 'VALUE',
|
||||||
//
|
//
|
||||||
// default: 123,
|
// default: 123,
|
||||||
@ -203,7 +205,6 @@ function(name, pre, post){
|
|||||||
// currently both '-' and '+' are supported.
|
// currently both '-' and '+' are supported.
|
||||||
//
|
//
|
||||||
// NOTE: essentially this parser is a very basic stack language...
|
// NOTE: essentially this parser is a very basic stack language...
|
||||||
// XXX can we implement the whole thing directly as a stack language???
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// XXX FEATURE (DELAYED): handle <scriptName>-<command> script calls...
|
// XXX FEATURE (DELAYED): handle <scriptName>-<command> script calls...
|
||||||
@ -215,8 +216,11 @@ function(name, pre, post){
|
|||||||
//
|
//
|
||||||
// XXX should type handlers produce errors???
|
// XXX should type handlers produce errors???
|
||||||
// XXX add support for ParserError exception handling...
|
// XXX add support for ParserError exception handling...
|
||||||
// XXX should -help should work for any command? ..not just nested parsers?
|
// XXX should -help work for any command? ..not just nested parsers?
|
||||||
// ...should we indicate which thinks have more "-help"??
|
// ...should we indicate which thinks have more "-help"??
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var Parser =
|
var Parser =
|
||||||
module.Parser =
|
module.Parser =
|
||||||
object.Constructor('Parser', {
|
object.Constructor('Parser', {
|
||||||
@ -232,10 +236,15 @@ object.Constructor('Parser', {
|
|||||||
.split(',')
|
.split(',')
|
||||||
.map(function(e){ return e.trim() }) },
|
.map(function(e){ return e.trim() }) },
|
||||||
},
|
},
|
||||||
|
|
||||||
valueCollectors: {
|
valueCollectors: {
|
||||||
string: function(v, cur){ return (cur || '') + v },
|
// format: 'string' | 'string|<separator>'
|
||||||
|
string: function(v, cur, sep){
|
||||||
|
return [...(cur ? [cur] : []), v]
|
||||||
|
.join(sep || '') },
|
||||||
list: function(v, cur){ return (cur || []).concat(v) },
|
list: function(v, cur){ return (cur || []).concat(v) },
|
||||||
set: function(v, cur){ return (cur || new Set()).add(v) },
|
set: function(v, cur){ return (cur || new Set()).add(v) },
|
||||||
|
// NOTE: this will ignore the actual value given...
|
||||||
toggle: function(v, cur){ return !cur },
|
toggle: function(v, cur){ return !cur },
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -251,7 +260,6 @@ object.Constructor('Parser', {
|
|||||||
optionInputPattern: /^([+-])\1?([^+-].*|)$/,
|
optionInputPattern: /^([+-])\1?([^+-].*|)$/,
|
||||||
commandInputPattern: /^([^-].*)$/,
|
commandInputPattern: /^([^-].*)$/,
|
||||||
|
|
||||||
|
|
||||||
// instance stuff...
|
// instance stuff...
|
||||||
// XXX do we need all three???
|
// XXX do we need all three???
|
||||||
script: null,
|
script: null,
|
||||||
@ -264,17 +272,7 @@ object.Constructor('Parser', {
|
|||||||
value: null,
|
value: null,
|
||||||
|
|
||||||
|
|
||||||
// output...
|
// Handler iterators...
|
||||||
//
|
|
||||||
print: afterCallback('print', null, function(...args){
|
|
||||||
console.log(...args)
|
|
||||||
return this }),
|
|
||||||
printError: afterCallback('print_error', null, function(...args){
|
|
||||||
console.error(this.scriptName+': Error:', ...args)
|
|
||||||
return this }),
|
|
||||||
|
|
||||||
|
|
||||||
// Handler API...
|
|
||||||
//
|
//
|
||||||
// Format:
|
// Format:
|
||||||
// [
|
// [
|
||||||
@ -336,10 +334,14 @@ object.Constructor('Parser', {
|
|||||||
return handler.required }) },
|
return handler.required }) },
|
||||||
commands: function(){
|
commands: function(){
|
||||||
return this.options(this.commandPrefix) },
|
return this.options(this.commandPrefix) },
|
||||||
|
|
||||||
isCommand: function(str){
|
isCommand: function(str){
|
||||||
return this.commandInputPattern.test(str)
|
return this.commandInputPattern.test(str)
|
||||||
&& ((this.commandPrefix + str) in this
|
&& ((this.commandPrefix + str) in this
|
||||||
|| this['@*']) },
|
|| this['@*']) },
|
||||||
|
|
||||||
|
// Get handler...
|
||||||
|
//
|
||||||
// NOTE: this ignores any arguments values present in the key...
|
// NOTE: this ignores any arguments values present in the key...
|
||||||
// NOTE: this ignores options forming alias loops and dead-end
|
// NOTE: this ignores options forming alias loops and dead-end
|
||||||
// options...
|
// options...
|
||||||
@ -368,6 +370,7 @@ object.Constructor('Parser', {
|
|||||||
[]
|
[]
|
||||||
: ['dead-end'])] },
|
: ['dead-end'])] },
|
||||||
|
|
||||||
|
// Trigger the handler...
|
||||||
//
|
//
|
||||||
// Get the handler for key and call it...
|
// Get the handler for key and call it...
|
||||||
// .handle(key, rest, _, value)
|
// .handle(key, rest, _, value)
|
||||||
@ -409,41 +412,8 @@ object.Constructor('Parser', {
|
|||||||
this.setHandlerValue(handler, key, res) }
|
this.setHandlerValue(handler, key, res) }
|
||||||
return res },
|
return res },
|
||||||
|
|
||||||
// set handler value...
|
|
||||||
//
|
|
||||||
// This handles handler.arg and basic name generation...
|
|
||||||
setHandlerValue: function(handler, key, value){
|
|
||||||
handler = handler
|
|
||||||
|| this.handler(key)[1]
|
|
||||||
|| {}
|
|
||||||
key = (handler.arg
|
|
||||||
&& handler.arg
|
|
||||||
.split(/\|/)
|
|
||||||
.pop()
|
|
||||||
.trim())
|
|
||||||
// get the final key...
|
|
||||||
|| this.handler(key)[0].slice(1)
|
|
||||||
// if value not given set true and handle...
|
|
||||||
//this[key] = arguments.length < 3 ?
|
|
||||||
value = arguments.length < 3 ?
|
|
||||||
(this.handleArgumentValue ?
|
|
||||||
this.handleArgumentValue(handler, true)
|
|
||||||
: true)
|
|
||||||
: value
|
|
||||||
var collect =
|
|
||||||
typeof(handler.collect) == 'function' ?
|
|
||||||
handler.collect
|
|
||||||
: (this.valueCollectors
|
|
||||||
|| this.constructor.valueCollectors
|
|
||||||
|| {})[handler.collect]
|
|
||||||
|
|
||||||
this[key] = collect ?
|
|
||||||
collect.call(this, value, this[key])
|
|
||||||
: value
|
|
||||||
|
|
||||||
return this },
|
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// Builtin options/commands and their configuration...
|
// Builtin options/commands and their configuration...
|
||||||
|
|
||||||
// Help...
|
// Help...
|
||||||
@ -672,13 +642,81 @@ object.Constructor('Parser', {
|
|||||||
'@*': '-*',
|
'@*': '-*',
|
||||||
|
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
// Output...
|
||||||
|
//
|
||||||
|
print: afterCallback('print', null, function(...args){
|
||||||
|
console.log(...args)
|
||||||
|
return this }),
|
||||||
|
printError: afterCallback('print_error', null, function(...args){
|
||||||
|
console.error(this.scriptName+': Error:', ...args)
|
||||||
|
return this }),
|
||||||
|
|
||||||
|
|
||||||
|
// Handle value via this/parent value handlers... (helper)
|
||||||
|
//
|
||||||
|
// Expected attr format:
|
||||||
|
//
|
||||||
|
// option_handler[attr] = '<handler-name>' | '<handler-name>|<arg>|...'
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// This will call the handler in this context with the following
|
||||||
|
// signature:
|
||||||
|
//
|
||||||
|
// handler(value, ...args, ...sargs)
|
||||||
|
//
|
||||||
|
// Where sargs is the list of arguments defined in attr via '|'.
|
||||||
|
//
|
||||||
|
// For an example see: .handleArgumentValue(..) and .setHandlerValue(..)
|
||||||
|
_handleValue: function(handler, attr, handlers, value, ...args){
|
||||||
|
var [h, ...sargs] =
|
||||||
|
typeof(handler[attr]) == typeof('str') ?
|
||||||
|
handler[attr].split(/\|/)
|
||||||
|
: []
|
||||||
|
var func =
|
||||||
|
typeof(handler[attr]) == 'function' ?
|
||||||
|
handler[attr]
|
||||||
|
: (this[handlers]
|
||||||
|
|| this.constructor[handlers]
|
||||||
|
|| {})[h]
|
||||||
|
return func ?
|
||||||
|
func.call(this, value, ...args, ...sargs)
|
||||||
|
: value },
|
||||||
|
|
||||||
|
// Set handler value... (helper)
|
||||||
|
//
|
||||||
|
// This handles handler.arg and basic name generation...
|
||||||
|
setHandlerValue: function(handler, key, value){
|
||||||
|
handler = handler
|
||||||
|
|| this.handler(key)[1]
|
||||||
|
|| {}
|
||||||
|
key = (handler.arg
|
||||||
|
&& handler.arg
|
||||||
|
.split(/\|/)
|
||||||
|
.pop()
|
||||||
|
.trim())
|
||||||
|
// get the final key...
|
||||||
|
|| this.handler(key)[0].slice(1)
|
||||||
|
// if value not given set true and handle...
|
||||||
|
//this[key] = arguments.length < 3 ?
|
||||||
|
value = arguments.length < 3 ?
|
||||||
|
(this.handleArgumentValue ?
|
||||||
|
this.handleArgumentValue(handler, true)
|
||||||
|
: true)
|
||||||
|
: value
|
||||||
|
|
||||||
|
this[key] = this._handleValue(handler, 'collect', 'valueCollectors', value, this[key])
|
||||||
|
|
||||||
|
return this },
|
||||||
|
|
||||||
|
|
||||||
// Default handler action...
|
// Default handler action...
|
||||||
//
|
//
|
||||||
// This is called when .handler is not set...
|
// This is called when .handler is not set...
|
||||||
handlerDefault: function(handler, rest, key, value){
|
handlerDefault: function(handler, rest, key, value){
|
||||||
return this.setHandlerValue(handler, ...[...arguments].slice(2)) },
|
return this.setHandlerValue(handler, ...[...arguments].slice(2)) },
|
||||||
|
|
||||||
|
|
||||||
// Handle argument value conversion...
|
// Handle argument value conversion...
|
||||||
//
|
//
|
||||||
// If this is false/undefined value is passed to the handler as-is...
|
// If this is false/undefined value is passed to the handler as-is...
|
||||||
@ -686,15 +724,7 @@ object.Constructor('Parser', {
|
|||||||
// NOTE: to disable this functionality just set:
|
// NOTE: to disable this functionality just set:
|
||||||
// handleArgumentValue: false
|
// handleArgumentValue: false
|
||||||
handleArgumentValue: function(handler, value){
|
handleArgumentValue: function(handler, value){
|
||||||
var convert =
|
return this._handleValue(handler, 'type', 'typeHandlers', value) },
|
||||||
typeof(handler.type) == 'function' ?
|
|
||||||
handler.type
|
|
||||||
: (this.typeHandlers
|
|
||||||
|| this.constructor.typeHandlers
|
|
||||||
|| {})[handler.type]
|
|
||||||
return convert ?
|
|
||||||
convert.call(this, value)
|
|
||||||
: value },
|
|
||||||
|
|
||||||
// Handle error exit...
|
// Handle error exit...
|
||||||
//
|
//
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ig-argv",
|
"name": "ig-argv",
|
||||||
"version": "2.3.0",
|
"version": "2.4.0",
|
||||||
"description": "simple argv parser",
|
"description": "simple argv parser",
|
||||||
"main": "argv.js",
|
"main": "argv.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user