At the moment we have multiple weird and wonderful ways of defining Cylc “objects” to operate on:
With the GraphQL schema came the requirement for a global identifier which added yet another format:
1) The global identifier is nicer and more flexible than the command line
2) It is not possible to specify jobs with any of the CLI formats.
3) The rose suite-run migration proposal
suggests converting the
FLOW) arguments into options i.e:
$ cylc stop --flow my_workflow
In order to make the edge where users wish to operate on a workflow and are already, conveniently, in the run directory of that workflow slightly nicer:
$ cd ~/cylc-run/my_workflow $ cylc stop
4) The UI currently doesn’t make use of any form of identifier, however, it may be beneficial to expose users to the global identifier e.g. for mutations 5) The CLI is now implemented via GraphQL anyway meaning that the CLI arguments are provided as GraphQL arguments and transformed as required.
/as the separator (as originally intended) but use
//to separate the flow from the cycle.
:<arg>as a special state selector for convenience in each section other than “user”. (i.e. a direct replacement for the current
cylc trigger flow *:failedsyntax).
# regular form (for identifying objects) [~user[/]]flow//cycle/task/job # expanded form with selectors (for quick querying of objects) [~user[/]]flow[:state]//cycle[:state]/task[:state]/job[:state]
Examples (equivalent GraphQL arguments under current scheme)
# flow under account user (wid="user|flow") ~user/flow # the task foo at all cycles in flow (wid="flow|*|foo") flow//*/foo # all tasks in cycles between (exclusive) 202009 202011 in flow # (wid="flow|202010*|*) flow//202010*/* # all tasks begining foo in flow (wid="flow|*|foo*) flow//*/foo* # all running workflows (wid="*", state="running") *:running # all cycles in foo with at least one running task # (wid="flow|*", state="running") flow//*:running # all running tasks in foo (wid="flow|*|*", state="running") flow//*/*:running
Note: All syntax implemented here represents functionality currently supported in the GraphQL schema.
Note: Currently in GraphQL
stateis a separate argument, there is no need to change that in GraphQL though it could be done for consistency if desired.
# don't match an empty string (?=.) # either match a user or the start of the line (?: (?: ~ (?P<user>[^\/:\n]+) # allow the match to end here (\/|$) ) |^ ) (?: (?P<flow>[^\/:\n~]+) (?: : (?P<flow_sel>[^\/:\n]+) )? (?: // (?: (?P<cycle>[^\/:\n]+) (?: : (?P<cycle_sel>[^\/:\n]+) (?: / (?: (?P<task>[^\/:\n]+) (?: : (?P<task_sel>[^\/:\n]+) )? (?: / (?: (?P<job>[^\/:\n]+) (?: : (?P<job_sel>[^\/:\n]+) )? )? )? )? )? )? )? )? )? $
We adapt the CLI to use this identifier in place of the following arguments:
cylc stop OPTIONS ID cylc stop my_workflow # currently: cylc stop my_workflow cylc stop my_workflow//123 # currently: cylc stop my_workflow 123 cylc stop my_workflow//123/task # currently: cylc stop my_workflow 123/task (or task.123) cylc trigger OPTIONS ID cylc trigger my_workflow//123/task # currently: cylc stop my_workflow 123/task (or task.123) cylc trigger my_workflow//123/*:failed # currently: cylc stop my_workflow 123/*:failed
cylc stop '*'.
Propose a new enhanced (and ridiculously simple) bash completion as a solution
to the “I would like to run Cylc commands for my workflow without having to
REG” use cases.
Note: This is psudocode to illustrate where the bash autocompletion would get its suggestions from.
# 𝄄 = the users cursor # autocomplete command name $ cylc 𝄄 echo $CMD_LIST # can be built during pip install (would pick up plugins) # autocomplete flow (REG) $ cylc trigger 𝄄 if [[ $1 == cylc && trigger == $FLOW_CMD_LIST ]]; then # the CLI is expecting a REG if [[ -d '.service' ]]; then # we are in the run dir echo $(basename "$PWD") elif [[ -d 'flow.cylc' ]]; then # we are in the src dir echo $(basename "$PWD") else # provide a list of workflows cylc scan --state=all --format=name fi fi # autocomplete cycle $ cylc trigger foo// 𝄄 echo ~/cylc-run/foo/log/job # autocomplete task $ cylc trigger foo//123 𝄄 echo ~/cylc-run/foo/log/job/123 | reverse # newest cycle points first # works with globs too $ cylc trigger foo//1* 𝄄 echo ~/cylc-run/foo/log/job/1* | reverse # newest cycle points first # autocomplete job $ cylc trigger foo//123/foo 𝄄 echo ~/cylc-run/foo/log/job/123/foo # autocomplete flow (REG) for another user $ cylc trigger ~user/ 𝄄 cylc scan --state=all --format=name --dir=~user/cylc-run # note the --dir arg would be a two line change to add
Propose the following interface for all commands which take
REG as an
cylc sub-commands ID [ID ...]
$ cylc trigger flow//cycle $ cylc trigger flow//cycle/* $ cylc trigger flow//cycle flow2//cycle2 flow3//cycle3
If the first argument stops at the
// and the following arguments start
// then they should be implicitly joined e.g:
# trigger cycles1, cycle2 and cycle3 in flow $ cylc trigger flow// //cycle1 //cycle2 //cycle3
// serving as the marker to the bash completion to glob cycle points.
We should be able to support the old legacy interface for the time being. Propose:
The following commands currently use the argument pattern
REG [TASK_GLOB ...]:
cylc [control] hold [OPTIONS] REG [TASK_GLOB ...]
cylc [control] kill [OPTIONS] REG [TASK_GLOB ...]
cylc [control] poll [OPTIONS] REG [TASK_GLOB ...]
cylc [control] release|unhold [OPTIONS] REG [TASK_GLOB ...]
cylc [control] remove [OPTIONS] REG TASK_GLOB [...]
cylc [info] show [OPTIONS] REG [TASK_NAME or TASK_GLOB ...]
cylc [control] trigger [OPTIONS] REG [TASK_GLOB ...]
These would change to
ID [ID ...], however, we can continue to support the
old syntax easily enough. If the first argument contains only user/workflow
information and more arguments are provided, assume we are in back-compat mode.
That leaves us with:
cylc [discovery] ping [OPTIONS] REG [TASK]
cylc [task] message [OPTIONS] -- [REG] [TASK-JOB] [[SEVERITY:]MESSAGE ...]
cycle/tasksyntax to ease transition.
$USER) then attempt to route via the UIS else fail.