diff --git a/cylc/flow/scripts/cylc.py b/cylc/flow/scripts/cylc.py
index 2dd56e9eacf..895af3aaf38 100644
--- a/cylc/flow/scripts/cylc.py
+++ b/cylc/flow/scripts/cylc.py
@@ -268,7 +268,7 @@ def get_version(long=False):
'start':
'cylc start & cylc restart have been replaced by cylc play',
'set-verbosity':
- 'cylc set-verbosity has been replaced by cylc log-level',
+ 'cylc set-verbosity has been replaced by cylc verbosity',
'warranty':
'cylc warranty has been replaced by cylc help license',
}
diff --git a/cylc/flow/scripts/set.py b/cylc/flow/scripts/set.py
index e8d4466199d..346f857c8af 100755
--- a/cylc/flow/scripts/set.py
+++ b/cylc/flow/scripts/set.py
@@ -59,12 +59,12 @@
FULL_ID_MULTI_ARG_DOC,
CylcOptionParser as COP,
)
+from cylc.flow.id import Tokens
from cylc.flow.terminal import cli_function
from cylc.flow.flow_mgr import (
add_flow_opts,
validate_flow_opts
)
-from cylc.flow.task_pool import REC_CLI_PREREQ
MUTATION = '''
@@ -126,6 +126,29 @@ def get_option_parser() -> COP:
return parser
+def validate_prereq(prereq: str) -> bool:
+ """Return True prereq string is valid, else False.
+
+ Examples:
+ Good prerequisite:
+ >>> validate_prereq('1/foo:succeeded')
+ True
+
+ Bad prerequisite:
+ >>> validate_prereq('1/foo::succeeded')
+ False
+
+ (That's sufficient, Tokens is fully tested elsewhere).
+
+ """
+ try:
+ Tokens(prereq)
+ except ValueError:
+ return False
+ else:
+ return True
+
+
def get_prerequisite_opts(options):
"""Convert prerequisite inputs to a single list, and validate.
@@ -149,9 +172,14 @@ def get_prerequisite_opts(options):
raise InputError("--pre=all must be used alone")
return result
- for p in result:
- if REC_CLI_PREREQ.match(p):
- raise InputError(f"Bad prerequisite: {p}")
+ msg = '\n'.join(
+ [
+ p for p in result
+ if not validate_prereq(p)
+ ]
+ )
+ if msg:
+ raise InputError(f"Invalid prerequisite(s):\n{msg}")
return result
diff --git a/cylc/flow/scripts/log_level.py b/cylc/flow/scripts/verbosity.py
similarity index 96%
rename from cylc/flow/scripts/log_level.py
rename to cylc/flow/scripts/verbosity.py
index 4d8f181d080..9cebaf63cc9 100755
--- a/cylc/flow/scripts/log_level.py
+++ b/cylc/flow/scripts/verbosity.py
@@ -16,9 +16,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-"""cylc log-level [OPTIONS] ARGS
+"""cylc verbosity [OPTIONS] ARGS
-Set the Python logging level of a running scheduler.
+Set the logging severity level of a running scheduler.
Messages at or above the chosen level are logged. If you choose
WARNING (say) only WARNING and CRITICAL messages will be logged.
diff --git a/cylc/flow/task_pool.py b/cylc/flow/task_pool.py
index ca326b14cf1..793b91c676e 100644
--- a/cylc/flow/task_pool.py
+++ b/cylc/flow/task_pool.py
@@ -16,7 +16,6 @@
"""Wrangle task proxies to manage the workflow."""
-import re
from contextlib import suppress
from collections import Counter
import json
@@ -73,6 +72,7 @@
from cylc.flow.flow_mgr import FLOW_ALL, FLOW_NONE, FLOW_NEW
+
if TYPE_CHECKING:
from queue import Queue
from cylc.flow.config import WorkflowConfig
@@ -83,16 +83,8 @@
from cylc.flow.workflow_db_mgr import WorkflowDatabaseManager
from cylc.flow.flow_mgr import FlowMgr, FlowNums
-Pool = Dict['PointBase', Dict[str, TaskProxy]]
-
-# CLI prerequisite pattern: point/name:label
-REC_CLI_PREREQ = re.compile(
- rf"({TaskID.POINT_RE})" +
- rf"{TaskID.DELIM2}" +
- rf"({TaskID.NAME_RE})" +
- r':' + r'(\w+)' # TODO: formally define qualifier RE?
-)
+Pool = Dict['PointBase', Dict[str, TaskProxy]]
class TaskPool:
@@ -1676,11 +1668,16 @@ def set_prereqs(self, point, taskdef, prereqs, flow_nums):
if prereqs == ["all"]:
itask.state.set_all_satisfied()
else:
- for pre in prereqs:
- m = REC_CLI_PREREQ.match(pre)
- if m is not None:
- itask.satisfy_me({m.groups()})
- # (regex already checked in the CLI)
+ # Pass individual prerequisites to itask.
+ itask.satisfy_me(
+ {
+ (t['cycle'], t['task'], t['task_sel'])
+ for t in [
+ Tokens(p, relative=True)
+ for p in prereqs
+ ]
+ }
+ )
self.data_store_mgr.delta_task_prerequisite(itask)
self.add_to_pool(itask)
diff --git a/setup.cfg b/setup.cfg
index 70fb8776e3c..1cfe55da7b6 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -189,11 +189,11 @@ cylc.command =
remove = cylc.flow.scripts.remove:main
report-timings = cylc.flow.scripts.report_timings:main [report-timings]
scan = cylc.flow.scripts.scan:cli
- log-level = cylc.flow.scripts.log_level:main
show = cylc.flow.scripts.show:main
set = cylc.flow.scripts.set:main
stop = cylc.flow.scripts.stop:main
subscribe = cylc.flow.scripts.subscribe:main
+ verbosity = cylc.flow.scripts.verbosity:main
workflow-state = cylc.flow.scripts.workflow_state:main
tui = cylc.flow.scripts.tui:main
trigger = cylc.flow.scripts.trigger:main
diff --git a/tests/functional/cli/03-log-level.t b/tests/functional/cli/03-verbosity.t
similarity index 89%
rename from tests/functional/cli/03-log-level.t
rename to tests/functional/cli/03-verbosity.t
index 6274e333816..eb66a4a8cfa 100755
--- a/tests/functional/cli/03-log-level.t
+++ b/tests/functional/cli/03-verbosity.t
@@ -15,13 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#-------------------------------------------------------------------------------
-# Test "cylc log-level"
+# Test "cylc verbosity"
. "$(dirname "$0")/test_header"
set_test_number 6
# Test illegal log level
TEST_NAME="${TEST_NAME_BASE}-bad"
-run_fail "$TEST_NAME" cylc log-level duck quack
+run_fail "$TEST_NAME" cylc verbosity duck quack
grep_ok 'InputError: Illegal logging level, duck' "${TEST_NAME}.stderr"
# Test good log level
@@ -37,10 +37,10 @@ __FLOW__
run_ok "${TEST_NAME}-validate" cylc validate "$WORKFLOW_NAME"
workflow_run_ok "${TEST_NAME}-run" cylc play --pause "$WORKFLOW_NAME"
-run_ok "$TEST_NAME" cylc log-level DEBUG "$WORKFLOW_NAME"
+run_ok "$TEST_NAME" cylc verbosity DEBUG "$WORKFLOW_NAME"
LOG_SCAN_GREP_OPTS="-E" \
log_scan "${TEST_NAME}-grep" "${WORKFLOW_RUN_DIR}/log/scheduler/log" 5 1 \
- '\[command] actioned.*set_log_level'
+ '\[command] actioned.*verbosity'
cylc stop "$WORKFLOW_NAME"
purge