At the moment we have multiple weird and wonderful ways of defining Cylc “objects” to operate on:
[CYCLE-POINT-GLOB/]TASK-NAME-GLOB[:TASK-STATE]
[CYCLE-POINT-GLOB/]FAMILY-NAME-GLOB[:TASK-STATE]
TASK-NAME-GLOB[.CYCLE-POINT-GLOB][:TASK-STATE]
FAMILY-NAME-GLOB[.CYCLE-POINT-GLOB][:TASK-STATE]
With the GraphQL schema came the requirement for a global identifier which added yet another format:
[user[|]]workflow[|cycle[|(namespace)[|job]]]
1) The global identifier is nicer and more flexible than the command line
options.
2) It is not possible to specify jobs with any of the CLI formats.
https://github.com/cylc/cylc-flow/pull/3880
3) The rose suite-run migration proposal
suggests converting the REG
(read 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.
resolves https://github.com/cylc/cylc-flow/issues/3592
/
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 *:failed
syntax).# 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
state
is a separate argument, there is no need to change that in GraphQL though it could be done for consistency if desired.
Reference regex:
https://regex101.com/r/XOOpUW/3
# 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:
REG
TASK_NAME
TASK-ID
TASK_GLOB
TASK-GLOB
TASK-JOB
Examples:
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
Benefits:
//
between the REG
and
TASK_GLOB
arguments.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
type the REG
” use cases.
Reference Implementation:
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
Benefits:
REG
.Motivations:
Propose the following interface for all commands which take REG
as an
argument:
cylc sub-commands ID [ID ...]
E.G:
$ 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
with //
then they should be implicitly joined e.g:
# trigger cycles1, cycle2 and cycle3 in flow
$ cylc trigger flow// //cycle1 //cycle2 //cycle3
The //
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/task
syntax to ease transition.cylc install
$USER
) then attempt to route
via the UIS else fail.task.cycle
, cycle/task
references.