From c57eef5a5f40954fa5155d6029caa7670ed45143 Mon Sep 17 00:00:00 2001
From: Tim Pillinger <26465611+wxtim@users.noreply.github.com>
Date: Mon, 4 Apr 2022 11:54:05 +0100
Subject: [PATCH 1/5] Ensure that fileinstall doesn't fail given the status of
asyncio loop
---
cylc/rose/entry_points.py | 9 ++-
.../functional/14_reinstall_fileinstall/data | 5 ++
.../dev-8.x/flow.cylc | 23 ++++++
.../14_reinstall_fileinstall/flow.cylc | 28 +++++++
.../14_reinstall_fileinstall/rose-suite.conf | 5 ++
.../functional/test_reinstall_fileinstall.py | 79 +++++++++++++++++++
6 files changed, 148 insertions(+), 1 deletion(-)
create mode 100644 tests/functional/14_reinstall_fileinstall/data
create mode 100644 tests/functional/14_reinstall_fileinstall/dev-8.x/flow.cylc
create mode 100644 tests/functional/14_reinstall_fileinstall/flow.cylc
create mode 100644 tests/functional/14_reinstall_fileinstall/rose-suite.conf
create mode 100644 tests/functional/test_reinstall_fileinstall.py
diff --git a/cylc/rose/entry_points.py b/cylc/rose/entry_points.py
index 4297e0d6..5bb0bba1 100644
--- a/cylc/rose/entry_points.py
+++ b/cylc/rose/entry_points.py
@@ -258,6 +258,7 @@ def rose_fileinstall(srcdir=None, opts=None, rundir=None):
raise exc
else:
# Carry out imports.
+ import asyncio
from metomi.rose.config_processor import ConfigProcessorsManager
from metomi.rose.popen import RosePopener
from metomi.rose.reporter import Reporter
@@ -274,7 +275,13 @@ def rose_fileinstall(srcdir=None, opts=None, rundir=None):
fs_util = FileSystemUtil(event_handler)
popen = RosePopener(event_handler)
- # Process files
+ # Get an Asyncio loop if one doesn't exist:
+ try:
+ asyncio.get_event_loop()
+ except RuntimeError:
+ asyncio.set_event_loop(asyncio.new_event_loop())
+
+ # Process fileinstall.
config_pm = ConfigProcessorsManager(event_handler, popen, fs_util)
config_pm(config_tree, "file")
finally:
diff --git a/tests/functional/14_reinstall_fileinstall/data b/tests/functional/14_reinstall_fileinstall/data
new file mode 100644
index 00000000..5e501c7b
--- /dev/null
+++ b/tests/functional/14_reinstall_fileinstall/data
@@ -0,0 +1,5 @@
+Hello World
+Bore Da
+Myttin Da
+Bon Jour
+Guten Tag
\ No newline at end of file
diff --git a/tests/functional/14_reinstall_fileinstall/dev-8.x/flow.cylc b/tests/functional/14_reinstall_fileinstall/dev-8.x/flow.cylc
new file mode 100644
index 00000000..1edec620
--- /dev/null
+++ b/tests/functional/14_reinstall_fileinstall/dev-8.x/flow.cylc
@@ -0,0 +1,23 @@
+[meta]
+title = "Boilerplate"
+description = """
+This workflow is designed to stop me having to
+write a pile of boilerplate from scratch.
+"""
+written for cylc version = 8.x
+
+[scheduler]
+ allow implicit tasks = true
+
+[scheduling]
+ initial cycle point = 1066
+ # final cycle point = 1067
+ [[dependencies]]
+ P1Y = foo
+
+[runtime]
+ [[root]]
+ script = """
+ echo $HOSTNAME
+ env
+ """
diff --git a/tests/functional/14_reinstall_fileinstall/flow.cylc b/tests/functional/14_reinstall_fileinstall/flow.cylc
new file mode 100644
index 00000000..62becba0
--- /dev/null
+++ b/tests/functional/14_reinstall_fileinstall/flow.cylc
@@ -0,0 +1,28 @@
+#!jinja2
+[meta]
+title = "%(workflow)"
+description = """
+This workflow is designed to stop me having to
+write a pile of boilerplate from scratch.
+"""
+written for cylc version = 8.x
+
+
+
+[scheduler]
+ allow implicit tasks = true
+
+
+[scheduling]
+ cycling mode = integer
+ initial cycle point = 1066
+ final cycle point = 1066
+ [[dependencies]]
+ P1 = foo
+
+[runtime]
+ [[root]]
+ script = """
+ echo $HOSTNAME
+ env
+ """
diff --git a/tests/functional/14_reinstall_fileinstall/rose-suite.conf b/tests/functional/14_reinstall_fileinstall/rose-suite.conf
new file mode 100644
index 00000000..31285256
--- /dev/null
+++ b/tests/functional/14_reinstall_fileinstall/rose-suite.conf
@@ -0,0 +1,5 @@
+[template variables]
+foo=42
+
+[file:data]
+source=data
\ No newline at end of file
diff --git a/tests/functional/test_reinstall_fileinstall.py b/tests/functional/test_reinstall_fileinstall.py
new file mode 100644
index 00000000..5a6d4bcf
--- /dev/null
+++ b/tests/functional/test_reinstall_fileinstall.py
@@ -0,0 +1,79 @@
+# THIS FILE IS PART OF THE ROSE-CYLC PLUGIN FOR THE CYLC WORKFLOW ENGINE.
+# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+"""Cylc reinstall is able to use the async fileinstall from rose without
+trouble.
+"""
+
+import os
+import pytest
+import shutil
+import subprocess
+
+from pathlib import Path
+from uuid import uuid4
+
+from cylc.flow.pathutil import get_workflow_run_dir
+
+
+WORKFLOW_SRC = Path(__file__).parent / '14_reinstall_fileinstall'
+
+
+@pytest.fixture(scope='module')
+def fixture_provide_flow(tmp_path_factory):
+ """Provide a cylc workflow based on the contents of a folder which can
+ be either validated or installed.
+ """
+ test_flow_name = f'cylc-rose-test-{str(uuid4())[:8]}'
+ srcpath = (tmp_path_factory.getbasetemp() / test_flow_name)
+ flowpath = Path(get_workflow_run_dir(test_flow_name))
+ shutil.copytree(WORKFLOW_SRC, srcpath)
+ (srcpath / 'opt').mkdir(exist_ok=True)
+ yield {
+ 'test_flow_name': test_flow_name,
+ 'flowpath': flowpath,
+ 'srcpath': srcpath
+ }
+ shutil.rmtree(srcpath)
+ shutil.rmtree(flowpath)
+
+
+def test_install_flow(fixture_provide_flow):
+ """Run ``cylc install``.
+ """
+ result = subprocess.run(
+ [
+ 'cylc', 'install',
+ '--flow-name', fixture_provide_flow['test_flow_name'],
+ '-C', str(fixture_provide_flow['srcpath'])
+ ],
+ capture_output=True,
+ env=os.environ
+ )
+ assert result.returncode == 0
+
+
+def test_reinstall_flow(fixture_provide_flow):
+ """Run ``cylc reinstall``.
+ """
+ result = subprocess.run(
+ [
+ 'cylc', 'reinstall',
+ fixture_provide_flow['test_flow_name'],
+ ],
+ capture_output=True,
+ env=os.environ
+ )
+ assert result.returncode == 0
From b3af13fabd6088f1701bf97c60217b9427adcc2d Mon Sep 17 00:00:00 2001
From: Tim Pillinger <26465611+wxtim@users.noreply.github.com>
Date: Mon, 4 Apr 2022 12:26:33 +0100
Subject: [PATCH 2/5] update changelog
---
CHANGES.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/CHANGES.md b/CHANGES.md
index 65fdfe7f..04137f09 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,13 @@
# Selected Cylc-Rose Changes
+## __cylc-rose-1.0.3 ()__
+
+### Fixes
+
+[130](https://github.com/cylc/cylc-rose/pull/130) - Fix bug preventing
+``cylc reinstall`` using Rose fileinstall.
+
+
## __cylc-rose-1.0.2 (Released 2022-03-24)__
### Fixes
From e0d97921b0f834f36b1bf05cab21169b9082f812 Mon Sep 17 00:00:00 2001
From: Tim Pillinger <26465611+wxtim@users.noreply.github.com>
Date: Mon, 4 Apr 2022 14:04:47 +0100
Subject: [PATCH 3/5] Update cylc/rose/entry_points.py
Co-authored-by: Oliver Sanders
---
cylc/rose/entry_points.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/cylc/rose/entry_points.py b/cylc/rose/entry_points.py
index 5bb0bba1..66511215 100644
--- a/cylc/rose/entry_points.py
+++ b/cylc/rose/entry_points.py
@@ -276,6 +276,9 @@ def rose_fileinstall(srcdir=None, opts=None, rundir=None):
popen = RosePopener(event_handler)
# Get an Asyncio loop if one doesn't exist:
+ # Rose may need an event loop to invoke async interfaces,
+ # doing this here incase we want to go async in cylc-rose.
+ # See https://github.com/cylc/cylc-rose/pull/130/files
try:
asyncio.get_event_loop()
except RuntimeError:
From 9392b79a59fb2376378d1dfe466b1c6aba86b391 Mon Sep 17 00:00:00 2001
From: Tim Pillinger <26465611+wxtim@users.noreply.github.com>
Date: Mon, 4 Apr 2022 15:50:04 +0100
Subject: [PATCH 4/5] flake8
---
tests/test_config_node.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_config_node.py b/tests/test_config_node.py
index e95a70cf..f7f4d342 100644
--- a/tests/test_config_node.py
+++ b/tests/test_config_node.py
@@ -151,7 +151,7 @@ def test_add_cylc_install_to_rose_conf_node_opts(rose_conf, cli_conf, expect):
expect_opt = ''
if 'opts' in cli_conf:
- expect_opt = cli_conf['opts']
+ expect_opt = cli_conf.get('opts')
expect_opt += ' (cylc-install)'
assert result.comments == [(
From 4a0093e0773e8e2e19098f7bfe360dd9129e0110 Mon Sep 17 00:00:00 2001
From: Tim Pillinger <26465611+wxtim@users.noreply.github.com>
Date: Tue, 5 Apr 2022 07:15:44 +0100
Subject: [PATCH 5/5] Response to review - Properly fixed a flake8 fail - Added
new lines at end of files.
---
tests/functional/14_reinstall_fileinstall/data | 2 +-
tests/functional/14_reinstall_fileinstall/rose-suite.conf | 2 +-
tests/test_config_node.py | 4 +---
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/tests/functional/14_reinstall_fileinstall/data b/tests/functional/14_reinstall_fileinstall/data
index 5e501c7b..6e17a24b 100644
--- a/tests/functional/14_reinstall_fileinstall/data
+++ b/tests/functional/14_reinstall_fileinstall/data
@@ -2,4 +2,4 @@ Hello World
Bore Da
Myttin Da
Bon Jour
-Guten Tag
\ No newline at end of file
+Guten Tag
diff --git a/tests/functional/14_reinstall_fileinstall/rose-suite.conf b/tests/functional/14_reinstall_fileinstall/rose-suite.conf
index 31285256..cb354f49 100644
--- a/tests/functional/14_reinstall_fileinstall/rose-suite.conf
+++ b/tests/functional/14_reinstall_fileinstall/rose-suite.conf
@@ -2,4 +2,4 @@
foo=42
[file:data]
-source=data
\ No newline at end of file
+source=data
diff --git a/tests/test_config_node.py b/tests/test_config_node.py
index f7f4d342..a07d7ff8 100644
--- a/tests/test_config_node.py
+++ b/tests/test_config_node.py
@@ -149,9 +149,7 @@ def test_add_cylc_install_to_rose_conf_node_opts(rose_conf, cli_conf, expect):
assert result.value == expect
- expect_opt = ''
- if 'opts' in cli_conf:
- expect_opt = cli_conf.get('opts')
+ expect_opt = cli_conf.get('opts', '')
expect_opt += ' (cylc-install)'
assert result.comments == [(