Since day one, customization has been a big thing in donna, with columns you can create and customize fully, or click modes & key modes that let you decide exactly which commands to trigger and when.
And while you could combine commands, either using the return value of a command
as argument for another one, or via special command
void(), there was no
scripting: no conditions, loops, or the likes.
This was on purpose, because this is Linux, there are already plenty of scripting languages out there, fast, powerful, and known; No need to add one more.
Instead, the plan was always to allow you to "script" donnatella using the language of your choice, and this would be done via a socket to communicate with donnatella.
donnatella adds a socket to open communication
On start, a socket is created as
PID is donnatella's process ID).
This socket will be used to send messages to, and receives messages from, donna.
A bit of "technical" talk
Messages sent via this socket must be the length of the message as string,
followed by a colon and the message. For example, to send
FOOBAR the message
sent shall be
Messages can either start with a command (nothing to do with donna's command), then a space and some arguments, or simply be a command.
donna will respond with a message starting with either "OK" or "ERR", the
command, and optionally extra information, separated by spaces. For example,
a full message could be
26:ERR FOOBAR Unknown command
If multiple commands were sent, the first response message will refer to the first one received/sent, since they're processed in the order they're received.
What can you do with this?
Pretty much, anything that can be done in donna. Let's take it slow: the first command is "VERSION" and doesn't take any arguments. The response will be the version number of donnatella.
The other command is "TRIGGER" and allows to trigger any node, i.e. it does indeed give full power to everything in donna. The given full location is parsed as expected, so prefixes/aliases are supported.
On success, an ID is given (e.g. "OK TRIGGER 1") which can then be used to cancel the task, should one want to.
It will also be used when the task reaches POST_RUN state, as either:
- "DONE <ID>[ <RETURN VALUE>]"
- "CANCELLED <ID>"
- "FAILED <ID>[ <ERROR MESSAGE>]
The return value will be as intref when it was a treeview, node, terminal, or an array (or nodes or strings).
Ideally scripts should free the intrefs they get once done, using new command
intref_free() If they fail to do so, intref-s will still be free after some
time as part of an internal's garbage collecting process.
A socket is nice, but maybe not easy to use...
You can of course use the socket directly from your script, but that might not be the easiest to do, so a little helper tool is introduced: donna-trigger
donna-trigger makes it easy to trigger nodes via donna's socket, e.g. from script. It takes a full location as argument, connects to donnatella's socket and sends a message to trigger it.
It then waits until the task is done, cancelled or failed. When done, the return value (if any) - or if it failed (or the TRIGGER failed, e.g. invalid location) the error message (if any) - will be printed on stdout.
Since it uses environment variable
DONNATELLA_SOCKET (set whenever executing
something from donna) one can simply do in bash e.g:
to trigger "foobar" and get the return value/error message in
$ret The return
code will indicate if it worked or not.
Where to get it?
For a a complete list of all changes/bug fixes please refer to the git log.
And in case you read all that and are wondering what donnatella is, or are looking for more information, download links, etc please refer to donnatella.
As always, bug reports, suggestions or any other form of constructive criticism is very much welcome. You can open issues on github, use the thread on Arch Linux forums, or simply email me.