Skip to content

Commit

Permalink
Address review comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
hjoliver committed Jun 14, 2024
1 parent bc709cb commit 1361908
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 30 deletions.
1 change: 1 addition & 0 deletions cylc/flow/option_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
OPT_WORKFLOW_ID_ARG_DOC = ('[WORKFLOW]', 'Workflow ID')
WORKFLOW_ID_MULTI_ARG_DOC = ('WORKFLOW ...', 'Workflow ID(s)')
WORKFLOW_ID_OR_PATH_ARG_DOC = ('WORKFLOW | PATH', 'Workflow ID or path')
ID_SEL_ARG_DOC = ('ID[:sel]', 'WORKFLOW-ID[[//CYCLE[/TASK]]:selector]')
ID_MULTI_ARG_DOC = ('ID ...', 'Workflow/Cycle/Family/Task ID(s)')
FULL_ID_MULTI_ARG_DOC = ('ID ...', 'Cycle/Family/Task ID(s)')

Expand Down
73 changes: 49 additions & 24 deletions cylc/flow/scripts/workflow_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@

r"""cylc workflow-state [OPTIONS] ARGS
Check a workflow database for current task statuses or completed outputs.
Check or poll a workflow database for task statuses or completed outputs.
Repeatedly check (poll) until results are matched or polling is exhausted
(see --max-polls and --interval). Use --max-polls=1 for a single check.
The ID argument can target a workflow, or a cycle point, or a specific
task, with an optional selector on cycle or task to match task status,
output trigger (if not a status, or with --trigger) or output message
(with --message). All matching results will be printed.
If no results match, the command will repeatedly check (poll) until a match
is found or polling is exhausted (see --max-polls and --interval). For a
one-off check set --max-polls=1.
If the database does not exist at first, polls are consumed waiting for it
so you can start checking before the target workflow is started.
Legacy (pre-8.3.0) options are supported, but deprecated, for existing scripts:
cylc workflow-state --task=NAME --point=CYCLE --status=STATUS
--output=MESSAGE --message=MESSAGE WORKFLOW
If the database does not exist at first, polls are consumed waiting for it.
--output=MESSAGE --message=MESSAGE --task-point WORKFLOW
(Note from 8.0 until 8.3.0 --output and --message both match task messages).
In "cycle/task:selector" the selector will match task statuses, unless:
- if it is not a known status, it will match task output triggers
Expand Down Expand Up @@ -90,6 +98,7 @@
"""

import asyncio
import os
import sqlite3
import sys
from typing import TYPE_CHECKING, List, Optional
Expand All @@ -98,7 +107,7 @@
from cylc.flow.id import Tokens
from cylc.flow.exceptions import InputError
from cylc.flow.option_parsers import (
ID_MULTI_ARG_DOC,
ID_SEL_ARG_DOC,
CylcOptionParser as COP,
)
from cylc.flow import LOG
Expand Down Expand Up @@ -269,7 +278,7 @@ async def check(self) -> bool:
def get_option_parser() -> COP:
parser = COP(
__doc__,
argdoc=[ID_MULTI_ARG_DOC]
argdoc=[ID_SEL_ARG_DOC]
)

# --run-dir for pre-8.3.0 back-compat
Expand Down Expand Up @@ -320,16 +329,15 @@ def get_option_parser() -> COP:
action="store", dest="depr_task", default=None)

parser.add_option(
"-p", "--point",
metavar="CYCLE",
"-p", "--point", metavar="CYCLE",
help=f"Cycle point. {OPT_DEPR_MSG}.",
action="store", dest="depr_point", default=None)

parser.add_option(
"-T", "--task-point",
help="In task job scripts, task cycle point from the environment"
" (i.e., --point=$CYLC_TASK_CYCLE_POINT)",
action="store_true", dest="use_task_point", default=False)
help="Get cycle point from the environment variable"
" $CYLC_TASK_CYCLE_POINT (e.g. in task job scripts)",
action="store_true", dest="depr_env_point", default=False)

parser.add_option(
"-S", "--status",
Expand Down Expand Up @@ -359,31 +367,45 @@ def main(parser: COP, options: 'Values', *ids: str) -> None:
# Note it would be cleaner to use 'id_cli.parse_ids()' here to get the
# workflow ID and tokens, but that function infers run number and fails
# if the workflow is not installed yet. We want to be able to start polling
# before the workflow is installed, which makes it easier to get set of
# before the workflow is installed, which makes it easier to get a set of
# interdependent workflows up and running, so runN inference is done inside
# the poller. TODO: consider using id_cli.parse_ids inside the poller.

if len(ids) != 1:
raise InputError("Please give a single ID")
# (Note this applies to polling tasks, which use the CLI, not xtriggers).

id_ = ids[0].rstrip('/') # might get 'id/' due to autcomplete

if any(
[
options.depr_task,
options.depr_status,
options.depr_msg, # --message and --output
options.depr_point
options.depr_msg, # --message and --trigger
options.depr_point,
options.depr_env_point
]
):
depr_opts = "options --task, --status, --message, --output, --point"
depr_opts = (
"--task, --status, --message, --output, --point, --task-point"
)

if id_ != Tokens(id_)["workflow"]:
raise InputError(

Check warning on line 391 in cylc/flow/scripts/workflow_state.py

View check run for this annotation

Codecov / codecov/patch

cylc/flow/scripts/workflow_state.py#L391

Added line #L391 was not covered by tests
f"with deprecated {depr_opts}, the argument must be a"
" plain workflow ID (i.e. with no cycle, task, or :selector)."
" plain workflow ID (i.e. no cycle, task, or :selector)."
)

if options.depr_status and options.depr_msg:
raise InputError("set --status or --message, not both.")

if options.depr_env_point:
if options.depr_point:
raise InputError(
"set --task-point or --point=CYCLE, not both.")
try:
options.depr_point = os.environ["CYLC_TASK_CYCLE_POINT"]
except KeyError:
raise InputError(
"--task-point: $CYLC_TASK_CYCLE_POINT is not defined")

if options.depr_point is not None:
id_ += f"//{options.depr_point}"
elif (
Expand All @@ -400,9 +422,12 @@ def main(parser: COP, options: 'Values', *ids: str) -> None:
id_ += f":{options.depr_msg}"
options.is_message = True

LOG.warning(
f"{depr_opts} are deprecated. Please use the ID format: {id_}."
)
msg = f"{depr_opts} are deprecated. Please use an ID: "
if not options.depr_env_point:
msg += id_
else:
msg += id_.replace(options.depr_point, "$CYLC_TASK_CYCLE_POINT")
LOG.warning(msg)

poller = WorkflowPoller(
id_,
Expand Down
7 changes: 2 additions & 5 deletions tests/functional/workflow-state/08-integer.t
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,18 @@

. "$(dirname "$0")/test_header"

set_test_number 16
set_test_number 15

install_workflow "${TEST_NAME_BASE}" integer

# run one cycle
TEST_NAME="${TEST_NAME_BASE}_run_1"
workflow_run_ok "${TEST_NAME}" cylc play --debug --no-detach --stopcp=1 "${WORKFLOW_NAME}"

# too many args
TEST_NAME="${TEST_NAME_BASE}_cl_error"
run_fail "${TEST_NAME}" cylc workflow-state --max-polls=1 "${WORKFLOW_NAME}-a" "${WORKFLOW_NAME}-b"

contains_ok "${TEST_NAME}.stderr" <<__END__
InputError: Please give a single ID
__END__

TEST_NAME="${TEST_NAME_BASE}_check_1_status"
run_ok "${TEST_NAME}" cylc workflow-state --max-polls=1 "${WORKFLOW_NAME}"

Expand Down
28 changes: 27 additions & 1 deletion tests/functional/workflow-state/11-multi.t
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

. "$(dirname "$0")/test_header"

set_test_number 35
set_test_number 42

install_workflow "${TEST_NAME_BASE}" "${TEST_NAME_BASE}"

Expand Down Expand Up @@ -101,4 +101,30 @@ run_fail "${T}-9" $CMD c8b --point=1 --task=foo --output="x"
run_fail "${T}-10" $CMD c8b --point=2
run_fail "${T}-11" $CMD c8b --point=2 --task=foo --status="succeeded"

#---------------
T=${TEST_NAME_BASE}-bad-cli

TEST_NAME="${T}-1"
run_fail "$TEST_NAME" $CMD c8b --status=succeeded --message="the quick brown"
cmp_ok "${TEST_NAME}.stderr" <<__ERR__
InputError: set --status or --message, not both.
__ERR__

TEST_NAME="${T}-2"
run_fail "$TEST_NAME" $CMD c8b --task-point --point=1
cmp_ok "${TEST_NAME}.stderr" <<__ERR__
InputError: set --task-point or --point=CYCLE, not both.
__ERR__


TEST_NAME="${T}-3"
run_fail "$TEST_NAME" $CMD c8b --task-point
cmp_ok "${TEST_NAME}.stderr" << "__ERR__"
InputError: --task-point: $CYLC_TASK_CYCLE_POINT is not defined
__ERR__

export CYLC_TASK_CYCLE_POINT=1
TEST_NAME="${T}-3"
run_ok "$TEST_NAME" $CMD c8b --task-point

purge

0 comments on commit 1361908

Please sign in to comment.