WIP: New builtin parse_args (implements #361)
I've started implementing a PoC for an argument parser as requested in #361 (closed)
Details
- This adds a new builtin (
parse_args
for now). - The builtin must be called with a list of arguments (e.g. typically
parse_args @args
) from within a script. - The builtin uses a (currently) hard-coded env variable (
SCRIPT_ARGS_DEFINITION
for now) which defines the argument parsing rules - For this, we use claps yaml format (third example on the linked page)
- After parsing (with clap) we store the results in a new env variable (also hard-coded name) as an Ion dictionary. not yet implemented
Necessary design decisions
- Better name suggestions for the name of the builtin?
- Should the builtin take the names of the env variables to use (yaml definition, where to store results)?
- What should we use as default names?
Current problems
Actually, the parsing is implemented, however, when passing -h
, --help
, -v
, or --version
to the script, it prints Ions' help/version and I dont know why :(
Edit: Actually, this is apparently caused because when invoking a script it passes all arguments to ion itself (which, in turn, will evaluate the -h
flags BEFORE executing the script..)
Also, I just discovered another issue: When calling parse_args -h
it will always print the help of the builtin, so this whole approach may not be usable :/ Any other ideas?
Examples of this behavior:
$ ./tests/parse_args.ion
args: [
On stack: 'parse_args',
On heap: './tests/parse_args.ion',
]
SCRIPT_ARGS_DEFINITION: On heap: 'name: myapp
version: "1.0"
author: Kevin K. <kbknapp@gmail.com>
about: Does awesome things
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- INPUT:
help: Sets the input file to use
required: true
index: 1
- verbose:
short: v
multiple: true
help: Sets the level of verbosity
subcommands:
- test:
about: controls testing features
version: "1.3"
author: Someone E. <someone_else@other.com>
args:
- debug:
short: d
help: print debug information
'
matches: Err(Error { message: "\u{1b}[1;31merror:\u{1b}[0m The following required arguments were not provided:\n \u{1b}[1;31m<INPUT>\u{1b}[0m\n\nUSAGE:\n parse_args.ion [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]\n\nFor more information try \u{1b}[32m--help\u{1b}[0m", kind: MissingRequiredArgument, info: None })
$ ./tests/parse_args.ion myinput
args: [
On stack: 'parse_args',
On heap: './tests/parse_args.ion',
On heap: 'myinput',
]
SCRIPT_ARGS_DEFINITION: On heap: 'name: myapp
version: "1.0"
author: Kevin K. <kbknapp@gmail.com>
about: Does awesome things
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- INPUT:
help: Sets the input file to use
required: true
index: 1
- verbose:
short: v
multiple: true
help: Sets the level of verbosity
subcommands:
- test:
about: controls testing features
version: "1.3"
author: Someone E. <someone_else@other.com>
args:
- debug:
short: d
help: print debug information
'
matches: Ok(ArgMatches { args: {"INPUT": MatchedArg { occurs: 1, indices: [1], vals: ["myinput"] }}, subcommand: None, usage: Some("USAGE:\n parse_args.ion [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]") })
$ ./tests/parse_args.ion myinput --config myconfig
args: [
On stack: 'parse_args',
On heap: './tests/parse_args.ion',
On heap: 'myinput',
On heap: '--config',
On heap: 'myconfig',
]
SCRIPT_ARGS_DEFINITION: On heap: 'name: myapp
version: "1.0"
author: Kevin K. <kbknapp@gmail.com>
about: Does awesome things
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- INPUT:
help: Sets the input file to use
required: true
index: 1
- verbose:
short: v
multiple: true
help: Sets the level of verbosity
subcommands:
- test:
about: controls testing features
version: "1.3"
author: Someone E. <someone_else@other.com>
args:
- debug:
short: d
help: print debug information
'
matches: Ok(ArgMatches { args: {"config": MatchedArg { occurs: 1, indices: [3], vals: ["myconfig"] }, "INPUT": MatchedArg { occurs: 1, indices: [1], vals: ["myinput"] }}, subcommand: None, usage: Some("USAGE:\n parse_args.ion [FLAGS] [OPTIONS] <INPUT> [SUBCOMMAND]") })
$ ./tests/parse_args.ion myinput --config myconfig -h
ion 1.0.0-alpha
The fast, safe, modern rust shell. Ion is a commandline shell created to be a faster and easier to use alternative to
the currently available shells. It is not POSIX compliant.
USAGE:
ion [FLAGS] [OPTIONS] [args]...
FLAGS:
-f, --fake-interactive Use a fake interactive mode, where errors don't exit the shell
-h, --help Prints help information
-i, --interactive Force interactive mode
-n, --no-execute Do not execute any commands, perform only syntax checking
-x Print commands before execution
-v, --version Print the version, platform and revision of Ion then exit
OPTIONS:
-c <command> Evaluate given commands instead of reading from the commandline
-o <key-bindings> Shortcut layout. Valid options: "vi", "emacs"
ARGS:
<args>... Script arguments (@args). If the -c option is not specified, the first parameter is taken as a
filename to execute
Edited by matu3ba