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--noname
to indicate#false
char
- 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 beforeproc
end
- 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 ...))