mirror of
https://github.com/flynx/argv.js.git
synced 2025-12-18 09:31:40 +00:00
cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
8c4f7a6cf2
commit
9be0f4ff35
32
README.md
32
README.md
@ -37,6 +37,7 @@ This code is an evolution of that parser.
|
||||
- Hooks for dynamic option/command handling
|
||||
- Customizable error and stop condition handling
|
||||
|
||||
|
||||
## Planned Features
|
||||
|
||||
- Run `<command>-<sub-command>` scripts
|
||||
@ -84,7 +85,7 @@ This code is an evolution of that parser.
|
||||
- [More control over help...](#more-control-over-help)
|
||||
- [Nested parsers](#nested-parsers)
|
||||
- [Components and API](#components-and-api)
|
||||
- [`THEN`, `STOP` and `ERROR`](#then-stop-and-error)
|
||||
- [`THEN`/ `STOP`](#then-stop)
|
||||
- [`ParserError(..)`](#parsererror)
|
||||
- [`Parser(..)`](#parser)
|
||||
- [`<parser>.then(..)`](#parserthen)
|
||||
@ -231,10 +232,12 @@ $ ./script.js -fb
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error reporting
|
||||
|
||||
XXX
|
||||
|
||||
|
||||
## XXX add subsections by task
|
||||
|
||||
XXX
|
||||
@ -242,6 +245,7 @@ XXX
|
||||
XXX might be a good idea to split out the rest to a INDETAIL.md or similar...
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
```
|
||||
@ -332,9 +336,9 @@ A _value_ can be passed either explicitly passed (via `=` syntax),
|
||||
implicitly parsed from the `argv` via the `<option>.arg` definition or
|
||||
is `undefined` otherwise.
|
||||
|
||||
A handler can return one of the `THEN`, `STOP` or `ERROR` to control
|
||||
further parsing and/or execution.
|
||||
(See: [`THEN`, `STOP` and `ERROR`](#then-stop-and-error) for more info.)
|
||||
A handler can return one of the `THEN`, `STOP` or `ParserError` instance
|
||||
to control further parsing and/or execution.
|
||||
(See: [`THEN` / `STOP`](#then-stop) for more info.)
|
||||
|
||||
|
||||
#### `<option>.doc`
|
||||
@ -468,6 +472,7 @@ argv.Parser.valueCollectors.Set = function(value, current, key){
|
||||
Defining handlers local to a parser instance handler is the same as for
|
||||
[type handlers](#optiontype) above.
|
||||
|
||||
|
||||
#### `<option>.env`
|
||||
|
||||
Determines the environment variable to be used as the default value for
|
||||
@ -691,26 +696,29 @@ See [lang.js](./lang.js) for more fun with argv and programming languages ;)
|
||||
|
||||
## Components and API
|
||||
|
||||
### `THEN`, `STOP` and `ERROR`
|
||||
### `THEN` / `STOP`
|
||||
|
||||
Values that if returned by option/command handlers can control the parse flow.
|
||||
|
||||
- `THEN` – Stop parsing and call `<parser>.then(..)` callbacks.
|
||||
- `STOP` – Stop parsing and call `<parser>.stop(..)` callbacks,
|
||||
skipping `<parser>.then(..)`.
|
||||
- `ERROR` – Stop parsing, call `<parser>.error(..)` callbacks and
|
||||
exit with an error.
|
||||
|
||||
|
||||
### `ParserError(..)`
|
||||
|
||||
A base error constructor, if an instance of `ParseError` is thrown by the
|
||||
handler it has the same effect as returning `ERROR` with one difference being
|
||||
that the error `.name`/`.message` will get printed.
|
||||
A base error constructor.
|
||||
|
||||
If an instance of `ParseError` is thrown or returned by the handler parsing
|
||||
is stopped, `<parsing>.error(..)` is called and then the parser will exit
|
||||
with an error (see: [`<parser>.handleErrorExit(..)`](#parserhandleerrorexit)).
|
||||
|
||||
The following error constructors are also defined:
|
||||
- `ParserTypeError(..)`
|
||||
- `ParserValueError(..)`
|
||||
|
||||
Note that `ParserError` instances can be both returned or thrown.
|
||||
|
||||
|
||||
### `Parser(..)`
|
||||
|
||||
@ -722,6 +730,7 @@ Parser(<spec>)
|
||||
|
||||
See [`<parser>(..)`](#parser-1) for more info.
|
||||
|
||||
|
||||
#### `<parser>.then(..)`
|
||||
|
||||
Add callback to `then` "event".
|
||||
@ -738,6 +747,7 @@ callback(<unhandled>, <root-value>, <rest>)
|
||||
`then` is triggered when parsing is done or stopped from an option
|
||||
handler by returning `THEN`.
|
||||
|
||||
|
||||
#### `<parser>.stop(..)`
|
||||
|
||||
Add callback to `stop` "event".
|
||||
@ -753,6 +763,7 @@ callback(<arg>, <rest>)
|
||||
|
||||
`stop` is triggered when a handler returns `STOP`.
|
||||
|
||||
|
||||
#### `<parser>.error(..)`
|
||||
|
||||
Add callback to `error` "event".
|
||||
@ -777,6 +788,7 @@ Remove callback from "event".
|
||||
-> <parser>
|
||||
```
|
||||
|
||||
|
||||
#### `<parser>(..)`
|
||||
|
||||
Execute the `parser` instance.
|
||||
|
||||
42
argv.js
42
argv.js
@ -33,9 +33,8 @@ module.STOP =
|
||||
module.THEN =
|
||||
{doc: 'break option processing, triggers .then(..) handlers'}
|
||||
|
||||
module.ERROR =
|
||||
{doc: 'option processing error, triggers .error(..) handlers'}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
module.ParserError =
|
||||
object.Constructor('ParserError', Error, {
|
||||
@ -664,8 +663,9 @@ object.Constructor('Parser', {
|
||||
doc: false,
|
||||
//section_doc: ...,
|
||||
handler: function(_, key){
|
||||
this.printError('unknown '+ (key.startsWith('-') ? 'option:' : 'command:'), key)
|
||||
return module.ERROR } },
|
||||
return this.printError(
|
||||
module.ParserError(
|
||||
`Unknown ${key.startsWith('-') ? 'option:' : 'command:'} ${ key }`)) } },
|
||||
'@*': '-*',
|
||||
|
||||
|
||||
@ -676,7 +676,18 @@ object.Constructor('Parser', {
|
||||
print: afterCallback('print', null, function(...args){
|
||||
console.log(...args)
|
||||
return this }),
|
||||
//
|
||||
// .printError(...)
|
||||
// -> this
|
||||
//
|
||||
// .printError(error, ...)
|
||||
// -> error
|
||||
//
|
||||
printError: afterCallback('print_error', null, function(...args){
|
||||
if(args[0] instanceof module.ParserError){
|
||||
console.error(
|
||||
this.scriptName+':', args[0].name+':', args[0].message, ...args.slice(1))
|
||||
return args[0] }
|
||||
console.error(this.scriptName+': Error:', ...args)
|
||||
return this }),
|
||||
|
||||
@ -838,6 +849,12 @@ object.Constructor('Parser', {
|
||||
parsed.error(reason, arg, rest)
|
||||
parsed.handleErrorExit
|
||||
&& parsed.handleErrorExit(arg, reason) }
|
||||
var reportError = function(message, arg, rest){
|
||||
message = message
|
||||
.replace(/$ARG/g, arg)
|
||||
handleError(message, arg, rest)
|
||||
return parsed.printError(
|
||||
module.ParserError(message)) }
|
||||
var runHandler = function(handler, arg, rest){
|
||||
var [arg, value] = arg instanceof Array ?
|
||||
arg
|
||||
@ -858,9 +875,7 @@ object.Constructor('Parser', {
|
||||
: value
|
||||
// required value check...
|
||||
if(handler.valueRequired && value == null){
|
||||
handleError('value missing', arg, rest)
|
||||
parsed.printError('value missing:', arg+'=?')
|
||||
return module.ERROR }
|
||||
return reportError('Value missing: $ARG=?', arg, rest) }
|
||||
|
||||
try {
|
||||
// run handler...
|
||||
@ -880,8 +895,6 @@ object.Constructor('Parser', {
|
||||
&& parsed.stop(arg, rest)
|
||||
res instanceof module.ParserError
|
||||
&& handleError(res, arg, rest)
|
||||
res === module.ERROR
|
||||
&& handleError('unknown', arg, rest)
|
||||
return res }
|
||||
// NOTE: if successful this needs to modify the arg, thus it
|
||||
// returns both the new first arg and the handler...
|
||||
@ -900,8 +913,7 @@ object.Constructor('Parser', {
|
||||
&& r.push(r.pop() +'='+ value)
|
||||
// push new options back to option "stack"...
|
||||
rest.splice(0, 0, ...r)
|
||||
var handler = parsed.handler(a)[1]
|
||||
return [a, handler] }
|
||||
return [ a, parsed.handler(a)[1] ] }
|
||||
|
||||
// parse/interpret the arguments and call handlers...
|
||||
var values = new Set()
|
||||
@ -936,9 +948,7 @@ object.Constructor('Parser', {
|
||||
|| parsed.handler(dfl)[1]
|
||||
// no handler found and '-*' or '@*' not defined...
|
||||
if(handler == null){
|
||||
handleError('unknown', arg, rest)
|
||||
parsed.printError('unknown '+(type == 'opt' ? 'option:' : 'command:'), arg)
|
||||
return module.ERROR }
|
||||
return reportError(`Unknown ${ type == 'opt' ? 'option' : 'command:' } $ARG`, arg, rest) }
|
||||
|
||||
// mark handler...
|
||||
;(handler.env || 'default' in handler)
|
||||
@ -949,7 +959,6 @@ object.Constructor('Parser', {
|
||||
|
||||
// handle stop conditions...
|
||||
if(res === module.STOP
|
||||
|| res === module.ERROR
|
||||
|| res instanceof module.ParserError){
|
||||
return nested ?
|
||||
res
|
||||
@ -981,8 +990,7 @@ object.Constructor('Parser', {
|
||||
.map(function([k, a, d, h]){
|
||||
return k.pop() })
|
||||
if(missing.length > 0){
|
||||
handleError('required', missing, rest)
|
||||
parsed.printError('required but missing:', missing.join(', '))
|
||||
reportError('required but missing: $ARG', missing.join(', '), rest)
|
||||
return parsed }
|
||||
|
||||
// handle root value...
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ig-argv",
|
||||
"version": "2.5.0",
|
||||
"version": "2.6.0",
|
||||
"description": "simple argv parser",
|
||||
"main": "argv.js",
|
||||
"scripts": {
|
||||
|
||||
6
test.js
6
test.js
@ -75,7 +75,7 @@ argv.Parser({
|
||||
},
|
||||
'-s': '-string',
|
||||
'-string': {
|
||||
doc: 'collect STR',
|
||||
doc: 'collect tab-separated strings',
|
||||
arg: 'STR | str',
|
||||
collect: 'string|\t',
|
||||
},
|
||||
@ -84,13 +84,13 @@ argv.Parser({
|
||||
doc: 'short option', },
|
||||
|
||||
'-type-error': {
|
||||
doc: 'throw an type error',
|
||||
doc: 'throw a type error',
|
||||
type: 'error',
|
||||
},
|
||||
'-error': {
|
||||
doc: 'throw an error',
|
||||
handler: function(){
|
||||
throw argv.ParserError('error') }},
|
||||
return argv.ParserError('error') }},
|
||||
|
||||
|
||||
'-test': argv.Parser({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user