I am writing a command line tool to copy files to or from locations, which can be a path inside a task inside a running Nomad task. The location can be either a stream or location on the local computer, or the location inside a Nomad task, where multiple "search" options are needed, each of them can be of any characters. To specify a Nomad task, I need an "allocation" name or a job name, optionally followed by the task name (if there are multiple tasks in the same allocation or job), optionally followed by the group name (if there are multiple tasks with the same name in the same allocation or job).
The tool is similar to docker cp
or scp
, but where scp
specifies path as [user@]host:[path]
or scp://[user@]hostname[:port][/path]
and docker cp
needs container_id:path
, I require more parameters to exactly pinpoint the task I am working on.
I am considering two designs of command line arguments. The first one is similar to rsync
or scp
, where the location can be specified in multiple ways with optional arguments along (:allocation|job)([:task[:group]]|[::group]):[path]
. Any of the following forms is valid, depending on how exactly the user wants or needs to specify the location:
# copy file ./source/file from the task within an allocation, if an allocation has only one task to ./destination/file
my-docker-cp :$allocation_name:./source/file ./destination/file
# copy from the task that is named $task_name inside allocation $allocation_name
my-docker-cp :$allocation_name:$task_name:./source/file ./destination/file
# copy from task $task_name inside group $group_name inside allocation $allocation_name
my-docker-cp :$allocation_name:$task_name:$group_name:./source/file ./destination/file
# copy from running task of $job_name, assert there is only one running task
my-docker-cp $job_name:./source/file ./destination/file
# copy from running task $task_nmae of job $job_name, assert there is only one such task
my-docker-cp $job_name:$task_name:./source/file ./destination/file
# copy from running task $task_name in group $group_name in job $job_name
my-docker-cp $job_name:$task_name:$group_name:./source/file ./destination/file
# copy file from job $job_name task $task1 to $task2
my-docker-cp $job_name:$task1:./source/file $job_name:$task2:/destination/file
This method is expressive and coincise. However, it requires escaping every :
with \"
in every $job_name
$task_name
./source/file
part of the path. This can be easily done in bash ${job_name//:/\\:}
. Developers can name jobs, groups and tasks anything, including any Unicode characters and emoticons, and including :
. I have not seen :
being used in these context (just like bash functions a:b() { echo 123; }
is not so often used), but it is a possibility some administrators will use :
for their names.
Maybe a different -
^
@
=
separator than :
is better?
In contrast, the same could be achieved with just command line options, where --from-alloc
--from-task
--from-group
--to-alloc
--to-task
--to-group
could be used. This would also allow specifying the group or task as something different, for example a regex, and allow for specifying the group without task.
# copy file ./source/file from the task within an allocation, if an allocation has only one task to ./destination/file
my-docker-cp --from-alloc "$allocation_name" ./source/file ./destination/file
# copy from the task that is named $task_name inside allocation $allocation_name
my-docker-cp --from-alloc "$allocation_name" --from-task "$task_name" \
./source/file ./destination/file
# copy from task $task_name inside group $group_name inside allocation $allocation_name
# --fa as shortcut of --from-alloc
# --ft as shortcut of --from-task
# --fg as shortcut of --from-group
my-docker-cp --fa $allocation_name --ft $task_name --fg $group_name \
./source/file ./destination/file
# copy from running task of $job_name, assert there is only one running task
# --fj as shortcut of --from-job
my-docker-cp --fj "$job_name" ./source/file ./destination/file
# copy file from job $job_name task $task1 to $task2
# --tj is shortcut of --to-job
# --tt is shortcut of --to-task
my-docker-cp --fj "$job_name" --ft "$task1" ./source/file \
--tj "$job_name" --tt "$task2" /destination/file
This method is way longer and allows switching order of arguments, however I do not know if this is a good enough argument. Although it is longer, it looks less expressive, but maybe this is my subjective view. And big win - no need to escape any :
, all paths will work as intended.
Which command line interface style will be the easiest and most intuitive for users?