Skip to content

Commit a29e8ef

Browse files
committed
Make a new standard template variable "CYLC_SOURCE_DIRECTORY"
available to users.
1 parent 8fe2e4a commit a29e8ef

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

changes.d/6944.feat.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make WORKFLOW_SOURCE_DIRECTORY available as a template variable.

cylc/flow/parsec/fileparse.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,11 @@ def read_and_proc(
471471
template_vars = merge_template_vars(template_vars, extra_vars)
472472
template_vars['CYLC_TEMPLATE_VARS'] = template_vars
473473

474+
# Add CYLC_SOURCE_DIRECTORY to template variables.
475+
sourcepath = get_workflow_source_dir(Path(fpath).parent)[1]
476+
template_vars['CYLC_SOURCE_DIRECTORY'] = (
477+
sourcepath.readlink() if sourcepath else Path(fpath).parent)
478+
474479
# Fail if templating_detected ≠ hashbang
475480
process_with = hashbang_and_plugin_templating_clash(
476481
extra_vars[TEMPLATING_DETECTED], flines
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#!/usr/bin/env bash
2+
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
3+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
#------------------------------------------------------------------------------
19+
# Test `cylc vip` (Validate Install Play)
20+
21+
. "$(dirname "$0")/test_header"
22+
23+
CYLC_ROSE=$(python -c """
24+
try:
25+
import cylc.rose
26+
print('true')
27+
except:
28+
print('false')
29+
""")
30+
31+
set_test_number 7
32+
33+
WORKFLOW_NAME="cylctb-x$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6)"
34+
35+
cat > flow.cylc <<__HERE__
36+
#!jinja2
37+
# TEST: {{ CYLC_SOURCE_DIRECTORY }}
38+
[scheduler]
39+
allow implicit tasks = true
40+
[scheduling]
41+
[[graph]]
42+
R1 = foo
43+
__HERE__
44+
45+
# It starts playing:
46+
run_ok "${TEST_NAME_BASE}-vip" \
47+
cylc vip \
48+
--pause \
49+
--no-run-name \
50+
--workflow-name ${WORKFLOW_NAME}
51+
52+
# It can get CYLC_SOURCE_DIRECTORY
53+
grep_ok "$PWD" "${RUN_DIR}/${WORKFLOW_NAME}/log/config/flow-processed.cylc"
54+
55+
# It can be updated with Cylc VR
56+
echo "[meta]" >> flow.cylc
57+
run_ok "${TEST_NAME_BASE}-vr" \
58+
cylc vr ${WORKFLOW_NAME}
59+
poll_grep "meta" "${RUN_DIR}/${WORKFLOW_NAME}/log/config/flow-processed.cylc"
60+
61+
# It can get CYLC_SOURCE_DIRECTORY
62+
grep_ok "$PWD" "${RUN_DIR}/${WORKFLOW_NAME}/log/config/flow-processed.cylc"
63+
64+
purge "${WORKFLOW_NAME}"
65+
66+
# If we have Cylc Rose installed, check that Rose Stem workflows
67+
# Also have access to WORKFLOW_SOURCE_DIR
68+
if [[ "$CYLC_ROSE" == 'false' ]]; then
69+
skip 3 "Install cylc-rose to run this test."
70+
exit 0
71+
else
72+
WORKFLOW_NAME="cylctb-x$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6)"
73+
mkdir rose-stem
74+
mv flow.cylc rose-stem/flow.cylc
75+
echo "ROSE_STEM_VERSION=1" > rose-stem/rose-suite.conf
76+
fi
77+
78+
run_ok "${TEST_NAME_BASE}-rose-stem" \
79+
rose stem \
80+
--source=${WORKFLOW_NAME}=${PWD} \
81+
--workflow-name ${WORKFLOW_NAME} \
82+
--no-run-name
83+
run_ok "${TEST_NAME_BASE}-run-rose-stem" \
84+
cylc play "${WORKFLOW_NAME}" --no-detach
85+
grep_ok "$PWD" "${RUN_DIR}/${WORKFLOW_NAME}/log/config/flow-processed.cylc"
86+
87+
purge "${WORKFLOW_NAME}"
88+
89+
exit 0

tests/integration/test_config.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
XtriggerConfigError,
3232
)
3333
from cylc.flow.parsec.exceptions import ListValueError
34+
from cylc.flow.parsec.fileparse import read_and_proc
3435
from cylc.flow.pathutil import get_workflow_run_pub_db_path
3536

3637
Fixture = Any
@@ -671,3 +672,45 @@ async def test_invalid_starttask(one_conf, flow, scheduler, start):
671672
with pytest.raises(InputError, match='a///b'):
672673
async with start(schd):
673674
pass
675+
676+
677+
async def test_CYLC_SOURCE_DIRECTORY_correctly_set(
678+
tmp_path, install, run_dir):
679+
"""CYLC_SOURCE_DIRECTORY is set correctly:
680+
681+
* In source dir
682+
* In installed dir (Not testing different permutations of installed
683+
dir as these are covered by testing of `get_workflow_source_dir`)
684+
* Created directly in the run dir.
685+
686+
"""
687+
def mock_cylc_view(target):
688+
"""Run config through read_and_proc (~= cylc view --process)
689+
"""
690+
return read_and_proc(
691+
target,
692+
viewcfg={
693+
'mark': False,
694+
'single': False,
695+
'label': False,
696+
'jinja2': True,
697+
'contin': True,
698+
'inline': True,
699+
},
700+
)
701+
702+
# Setup a source directory:
703+
(tmp_path / 'flow.cylc').write_text(
704+
'#!jinja2\n{{ CYLC_SOURCE_DIRECTORY }}'
705+
)
706+
707+
# Check that the CYLC_SRC_DIRECTORY
708+
# points to the source directory (tmp_path):
709+
processed = mock_cylc_view(tmp_path / 'flow.cylc')
710+
assert processed[0] == str(tmp_path)
711+
712+
# After installation the CYLC_SOURCE_DIRECTORY
713+
# *still* points back to tmp_path:
714+
wid = await install(tmp_path)
715+
processed = mock_cylc_view(run_dir / wid / 'flow.cylc')
716+
assert processed[0] == str(tmp_path)

0 commit comments

Comments
 (0)