Glitzersachen
On glitter things found at the road sideReleasing Romulan 1.0.0 (first release)
I am hereby releasing the first version (1.0.0) of Romulan. The source is available on Gitlab and on Github. The primary site is, for the moment, Gitlab.
Romulan is a declarative interface for the Common Lisp command line parser clingon.
Romulan is currently work in progress. Defining an application with subcommands already works (see example below). For more planned development (= features that do not exist yet, but will some time in the future), see the section Future development in the README.
Example
As already mentioned above only subcommand interfaces (also called git or svn style) can currently be defined in Romulan. Those are interfaces where the command line looks like:
$ ./example-script-2 --user=Jim hello Hello, Jim! $ .//example-script-2 shout go for it GO FOR IT, rak1912!
The words hello and shout are called subcommands here.
You will find the following Romulan example in file example-script-2
in the Romulan source, a
slightly larger example in example-script
.
In Romulan an interface with subcommands is declared with
commandline-subcommand-interface
. The declaration needs to contain at
least a usage string (that is later used to construct help text) and the
definition of global options:
(commandline-subcommand-interface romulan-test "shout some words or say hello" :usage "[-v] [-u <user>] <command> [options ...]" :options (:user (:description "user to greet" :short-name #\u :env-vars ("USER"))))
Invoking the command without any options will display a help text that describes usage and global options from the definition above and lists the subcommands (all this courtesy of clingon, Romulan just adds defaults and reformats the definitions in a slightly different format for clingon).
$ ./example-script-2 NAME: romulan-test - shout some words or say hello USAGE: romulan-test [-v] [-u <user>] <command> [options ...] OPTIONS: --help display usage information and exit --version display version and exit -u, --user <VALUE> user to greet [env: $USER] COMMANDS: shout shouts back anything you write hello just says hello
Subcommands are defined with define-subcommands
and look mostly like
function definitions with additional arguments that specify usage,
one-line help text and the subcommand options.
(define-subcommand hello (&key user) (:description "just says hello") (format t "Hello, ~A!~%" user)) (define-subcommand shout (words &key user) (:description "shouts back anything you write" :usage "[options ...] [arguments ...]" :varargs t) (format t "~{~A~^ ~}, ~A!~%" (mapcar #'string-upcase words) user))
All subcommands are indeed procedures. The &key
parameters of the
lambda list correspond to options which will be automatically bound
when invoking the subcommand. The positional parameters will be bound
from the positional arguments of the POSIX argument vector.
When all sub-commands are defined, end-subcommand-interface
must be
invoked. This actually builds the interfaces declared with
commandline-subcommand-interface
.
(end-subcommand-interface)
The command line interface thus defined is bound as a procedure to the
symbol given to commandline-subcommand-interface
and can be invoked as
a procedure to process the command-line arguments and invoke the
subcommands.
(romulan-test)
The subcommands are themselves procedures and can simply be called from Lisp (e.g. for testing) like any procedure:
(hello :user "Jim) Hello, Jim!
Comments
Due to legal pitfalls in Europe there is no comment section in this blog at the moment (sorry), but you can discuss this article or comment on its content ⮕ here on Mastodon.