Use tool of your choice to perform IO operations in donnatella
A few changes have just been pushed to branch next
of donnatella, introducing
some changes when it comes to IO operations (i.e. copy/move/delete files).
Starting at the top: donnatella doesn't perform any such IO operations itself. This isn't a not-yet-implemented feature but a design choice: there are plenty of tools which specialized in such things, no need to re-invent the wheel, let's use the existing ones instead!
So when you copy/move/delete files in donna, it will actually run cp/mp/rm to perform the operation (parsing the output to determine what was done/ask confirmations/etc).
This is good, but quite limited. In fact, when it comes to GUI operations one might expect to have, in case e.g. a file already exists, a detailled window with information about both files, and possibilities to skip, overwrite, rename, etc.
None of that is currently possible, though - truth be told - it's on a todo list of mine (though not as part of donna, but an external tool).
IO Engines
To try to maybe help and offer more possibilities, donna now introduces the notion of IO engines, giving you the ability to choose which one to use.
New options providers/fs/engine_{copy,move,delete}
have been added, and must
be set to the name of the IO engine to use to perform copy, move or delete
operations respectively.
By default, donna uses the basic
IO engine, the one "wrapping" cp/mv/rm as
needed. But another one is now avaialable as well, called exec
IO Engine "exec"
This engine simply allows you to specify a command line to be executed to perform the corresponding IO operation. Therefore, you can now use about any tool you want to perform IO operation in donna, e.g. use rsync to copy files.
As you may know, in donna an IO operation comes from command nodes_io()
where
the source(s), destination (if any) and type of operation (copy/move/delete) are
specified.
Optionally, for copy/move operation with a single source, a new name can be specified, to rename the item as it is copied/moved.
The command-line to be used when IO engine exec is used are defined under
providers/fs/ioengine-exec
and are named:
copy_cmdline
: for copy operationscopy_cmdline_new_name
: for copy operations with a new name specified (implies a single source)move_cmdline
: for move operationsmove_cmdline_new_name
: for move operations with a new name specified (implies a single source)delete_cmdline
: for delete operations
Those command-lines support the following variables :
%s
: the source node(s)%d
: the destination node%n
: the new name
It should be noted that because behind %s
and %d
are nodes, they should
most likely be used with FS dereferencing, e.g. cp -irvat %:d %:s
Similarly, you'll want to use %'n
to have the new name escaped in a
shell-compatible way.
The options allow you to define a command line, but the way it will be processed is actually as a location in provider "exec" which means that, for instance, you can use supported prefixes to e.g. execute it inside a(n embedded) terminal.
Limitations
It is important to note that nodes_io()
usually returns an array of nodes, of
the copied/moved files. This is obviously not possible when using IO engine
"exec" since it has no awareness of what actually gets done.
As a result, using it will have the command return nothing, which could lead to errors if you tried to get/used the command's return value furthermore. For such cases, you might need to use another engine (e.g basic).
Command fs_nodes_io()
A new command has also been added, which works just like nodes_io()
except
that :
- it takes an extra optional argument, the name of the IO engine to use;
- if said argument isn't specified, different default options
(
fs_engine_{copy,move,delete}
) are used before falling back to the main ones (engine_{copy,move,delete}
).
Example
As an example, one could decide to have e.g. copy and move operations be done via a small script wrapping cp/mv and to be run inside an embedded terminal.
To do so, one could set it up like so (note that we set the default for
fs_nodes_io()
back to "basic" so we can use that function to use the basic IO
engine easilly) :
[providers/fs]
engine_copy=exec
engine_move=exec
fs_engine_copy=basic
fs_engine_move=basic
[providers/fs/ioengine-exec]
copy_cmdline=!!donna-io cp %:d %:s
copy_cmdline_new_name=!!donna-io cp-nn %:d %'n %:s
move_cmdline=!!donna-io mv %:d %:s
move_cmdline_new_name=!!donna-io mv-nn %:d %'n %:s
And the script in question could look something like this:
- #!/bin/bash
- ALL_OFF="\e[0m"
- BOLD="\e[1m"
- BLUE="${BOLD}\e[34m"
- GREEN="${BOLD}\e[32m"
- RED="${BOLD}\e[31m"
- YELLOW="${BOLD}\e[33m"
- msg() {
- local mesg=$1; shift
- printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
- }
- error() {
- local mesg=$1; shift
- printf "${RED}==> ERROR:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
- }
- err() {
- error "$@"
- exit 1
- }
- op=$1
- shift
- nn=0
- case $op in
- "copy"|"cp")
- op="cp"
- action="Copying"
- ;;
- "copy-new-name"|"cp-nn")
- op="cp-nn"
- action="Copying"
- nn=1
- ;;
- "move"|"mv")
- op="mv"
- action="Moving"
- ;;
- "move-new-name"|"mv-nn")
- op="mv-nn"
- action="Moving"
- nn=1
- ;;
- "delete"|"rm")
- op="rm"
- action="Deleting"
- ;;
- *)
- err "invalid operation '$op': must be 'copy', 'move' or 'delete'"
- ;;
- esac
- if [[ $op = "rm" ]]; then
- nb=$#
- if [[ $nb -gt 1 ]]; then
- msg "$action $nb files..."
- elif [[ $nb -eq 1 ]]; then
- msg "$action $1..."
- else
- err "missing source(s)"
- fi
- else
- dest=$1
- shift
- if [[ $nn -eq 1 ]]; then
- new_name=$1
- shift
- fi
- nb=$#
- if [[ $nn -eq 1 ]]; then
- msg "$action $1 as $dest/$new_name..."
- elif [[ $nb -gt 1 ]]; then
- msg "$action $nb files to $dest..."
- elif [[ $nb -eq 1 ]]; then
- msg "$action $1 to $dest..."
- else
- err "missing source(s)"
- fi
- fi
- echo
- case $op in
- "cp")
- cp -irvat "$dest" "$@"
- ;;
- "cp-nn")
- cp -irvaT "$@" "$d/$new_name"
- ;;
- "mv")
- mv -ivt "$dest" "$@"
- ;;
- "mv-nn")
- mv -ivT "$@" "$dest/$new_name"
- ;;
- "rm")
- rm -Irv "$@"
- ;;
- esac
- echo
- msg "done"
Where to get it?
For Arch Linux users, you can use donnatella-git in the AUR to easilly get it. Or simply clone the git repo from github and compile things yourself.
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.