Unified command-line option parsing and config management.
The high-level interface. Given an application specspec,
parses the given command-line arguments args into a config
object, prepended to the existing object config if given.
Then runs the corresponding command (or sub-command) procedure
from spec.
The app spec should be a list of the form:
(<command> [<doc-string>] <clauses> ...)
where clauses can be any of:
(@ <opt-spec>)- option spec, described below(begin: <begin-proc>)- procedure to run before main(end: <end-proc>)- procedure to run after main(<proc> args ...)- main procedure (args only for documentation)<app-spec>- a subcommand described by the nested spec(or <app-spec> ...)- an alternate list of subcommands
begin and end procedures can be
useful for loading and saving state common to all subcommands.
The opt-spec describes command-line options, and is a
simple list with each opt of the form:
(<name> <type> [(<aliases> ...)] [<doc-string>])
where <name> is a symbol name, <aliases> is an
optional list of strings (for long options) or characters (for
short options) to serve as aliases in addition to the exact name.
type can be any of:
boolean- boolean, associated value optional, allowing--nonameto indicate#falsechar- a single characterinteger- an exact integerreal- any real numbernumber- any real or complex numbersymbol- a symbolstring- a stringsexp- a sexp parsed withread(list <type>)- a comma-delimited list of types
quasiquote.
Complete Example:
(run-application
`(zoo
"Zookeeper Application"
(@
(animals (list symbol) "list of animals to act on (default all)")
(lions boolean (#l) "also apply the action to lions"))
(or
(feed "feed the animals" () (,feed animals ...))
(wash "wash the animals" (@ (soap boolean)) (,wash animals ...))
(help "print help" (,app-help-command))))
(command-line)
(conf-load (string-append (get-environment-variable "HOME") "/.zoo")))
The second and third arguments here are optional, provided to show
the common pattern of allowing the same options to be specified
either in a file and/or on the command-line. The above app can be
run as:
Feed all animals, including lions:
zoo -l feed
Wash the elephants with soap:
zoo --animals=elephant wash --soap
Print help:
zoo help
The application procedures themselves are of the form:
(proc cfg spec args ...)
where cfg is a config object from (chibi config)
holding the parsed option info, spec is the original app
spec, and args are the remaining non-option command-line
arguments.
To retrieve the options for the above example you can use:
(conf-get cfg 'animals)(conf-get cfg 'lions)(conf-get cfg '(command wash soap))
(command <name>) prefix, so that you can use the same
name for different subcommands without conflict. This also means
the subcommand options are distinct from the top-level options, so
when using subcommands users must always write the command line
as:
app [<general options>] <subcommand> [<sub options>]
The ~/.zoo file could then hold an sexp of the form:
((animals (camel elephant rhinocerous))
(command
(wash
(soap #t))))
Parse a single command-line argument from args according to
conf-spec, and returns a list of two values: the
(name value) for the option, and a list of remaining
unparsed args. name will have the current prefix
prepended. If a parse error or unknown option is found, calls
fail with a single string argument describing the error,
returning that result.Parse a list of command-line arguments into a config object.
Returns a list whose head is the resulting config object, and tail
is the list of remaining non-option arguments. Calls fail on
error and tries to continue processing from the result.Parses a list of command-line arguments args according to
the application spec opt-spec. Returns a vector of five
elements:
proc- procedure to run the applicationconfig- a config object containing all parsed optionsargs- a list of remaining unparsed command-line argumentsinit- an optional procedure to call beforeprocend- an optional procedure to call afterproc
config, with option names
all prefixed by prefix. The original spec is used for
app-help.Print a help summary for the given application spec spec.The subcommand form of app-help. You can use this as a
subcommand in an application spec, for example as:
(help "print help" (,app-help-command args ...))