0
\$\begingroup\$

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?

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Unfortunately, in the current form the question is off-topic here. This site reviews code. Generic best practices are specifically excluded. \$\endgroup\$
    – vnp
    Commented Feb 14 at 16:30
  • \$\begingroup\$ I agree. Do you know if there exists a stackexchnage site for generic best practices? \$\endgroup\$
    – KamilCuk
    Commented Feb 14 at 17:23
  • 1
    \$\begingroup\$ Software Engineering, perhaps? \$\endgroup\$
    – vnp
    Commented Feb 14 at 17:28

1 Answer 1

1
\$\begingroup\$

Maybe a different - ^ @ = separator than : is better?

I take - dash to be the most innocuous of those. Remember that double or triple dash could be used, but also that some keyboard environments will turn them into n-dash or m-dash, so consider -=- for separating multiple fields.


It sounds like you have an inconveniently large number of args. Consider inventing some "super arg" noun which aggregates a few argument values that usually go together, and present "alternative" forms when displaying messages. This could get your users in the habit of copy-n-pasting those alternative aggregates.

I appreciate your "escaping the : colons" concern. Sounds like colons need to go, replaced by dashes.

I have not seen : being used in these context

Recommend you prohibit that character. Just design it out of the problem space. People will use ; semicolon if they really need to.

I find it amazing that various desktop GUIs will let me create files with names like
development / investments .txt, and then poor unsuspecting apps need to worry about such details. Be conservative, and prohibit troublesome characters.

Developers can name jobs, groups and tasks anything, including any Unicode characters and emoticons,

Honestly, that doesn't sound like a good design goal. At a minimum, insist on such spellings being canonicalized, so for example we don't have random variations of combining diacritics and so on.

Python goes pretty far in letting you define unicode names, such as a tiny epsilon. But fortunately it does have its limits, and won't let you say that two is three.

>>> ϵ = 1e-12
>>> 
>>> 10 * ϵ
1e-11
>>> 
>>> ٢ = 3
  File "<stdin>", line 1
    ٢ = 3
    ^
SyntaxError: invalid character '٢' (U+0662)

Consider paying attention to unicode character classes, in addition to canonicalizing.


URI schema

It's unclear why you rejected the scp://... approach. Pick a schema name, and run with it.

Even if we were to cram those parameters into the HTTP namespace, specifying
.../endpoint?from-alloc=1&from-task=2&from-group=3&to-job=4&to-task=5 doesn't seem so bad. People will copy-n-paste much of it, anyway.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you. - is often used for task or job names, like airflow-init nexus-dev etc, so I wouldn't want users to type my-nomad-cp /etc/nexus.conf nexus\-dev-/etc/nexus.conf. What do you think about ^ or @ as separator? I haven't seen ^ used in shell that often and I do not think it has any special meaning in any contexts. How does nexus-dev^nexus^/etc/nexus.conf look like? \$\endgroup\$
    – KamilCuk
    Commented Feb 13 at 22:50
  • 1
    \$\begingroup\$ I always worry about ^ circumflex, as Bourne at least used to use it, so Bash and others tend to offer back compat support. The @ at is innocuous enough from a punctuation perspective. But it makes humans think of “identity”, or at least “location”, which could be good or bad. We don’t tend to see more than one in a given context. (And you really don’t want to know about uucp / CSnet email addresses.) \$\endgroup\$
    – J_H
    Commented Feb 13 at 23:04
  • \$\begingroup\$ Hi, the URL schema is great and very flexible. Thank you for mentioning URL query parameters, they actually work ok. \$\endgroup\$
    – KamilCuk
    Commented Feb 14 at 17:24

Not the answer you're looking for? Browse other questions tagged or ask your own question.