def get_rose_vars(srcdir=None, opts=None): """Load template variables from Rose suite configuration. Loads the Rose suite configuration tree from the filesystem using the shell environment. Args: srcdir(pathlib.Path): Path to the Rose suite configuration (the directory containing the ``rose-suite.conf`` file). opts: Options object containing specification of optional configuarations set by the CLI. Returns: dict - A dictionary of sections of rose-suite.conf. For each section either a dictionary or None is returned. E.g. { 'env': {'MYVAR': 42}, 'empy:suite.rc': None, 'jinja2:suite.rc': { 'myJinja2Var': {'yes': 'it is a dictionary!'} } } """ # Set up blank page for returns. config = { 'env': {}, 'template_variables': {}, 'templating_detected': None } # Return a blank config dict if srcdir does not exist if not rose_config_exists(srcdir, opts): if ( getattr(opts, "opt_conf_keys", None) or getattr(opts, "defines", None) or getattr(opts, "rose_template_vars", None) ): raise NotARoseSuiteException() return config # Load the raw config tree config_tree = rose_config_tree_loader(srcdir, opts) deprecation_warnings(config_tree) # Extract templatevars from the configuration get_rose_vars_from_config_node( config, config_tree.node, os.environ ) # Export environment vars for key, val in config['env'].items(): os.environ[key] = val return config
def rose_fileinstall(srcdir=None, opts=None, rundir=None): """Call Rose Fileinstall. Args: srcdir(pathlib.Path): Search for a ``rose-suite.conf`` file in this location. rundir (pathlib.Path) """ if not rose_config_exists(rundir, opts): return False # Load the config tree config_tree = rose_config_tree_loader(rundir, opts) if any(i.startswith('file') for i in config_tree.node.value): try: startpoint = os.getcwd() os.chdir(rundir) except FileNotFoundError as exc: 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 from metomi.rose.fs_util import FileSystemUtil # Update config tree with install location # NOTE-TO-SELF: value=os.environ["CYLC_WORKFLOW_RUN_DIR"] config_tree.node = config_tree.node.set( keys=["file-install-root"], value=str(rundir) ) # Artificially set rose to verbose. event_handler = Reporter(3) fs_util = FileSystemUtil(event_handler) 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: asyncio.set_event_loop(asyncio.new_event_loop()) # Process fileinstall. config_pm = ConfigProcessorsManager(event_handler, popen, fs_util) config_pm(config_tree, "file") finally: os.chdir(startpoint) return config_tree.node
def get_rose_vars(srcdir=None, opts=None): """Load template variables from Rose suite configuration. Loads the Rose suite configuration tree from the filesystem using the shell environment. Args: srcdir(pathlib.Path): Path to the Rose suite configuration (the directory containing the ``rose-suite.conf`` file). opts: Options object containing specification of optional configuarations set by the CLI. Returns: dict - A dictionary of sections of rose-suite.conf. For each section either a dictionary or None is returned. E.g. { 'env': {'MYVAR': 42}, 'empy:suite.rc': None, 'jinja2:suite.rc': { 'myJinja2Var': {'yes': 'it is a dictionary!'} } } """ # Set up blank page for returns. config = {'env': {}, 'template_variables': {}, 'templating_detected': None} # Return a blank config dict if srcdir does not exist if not rose_config_exists(srcdir, opts): return config # Load the raw config tree config_tree = rose_config_tree_loader(srcdir, opts) # Warn if root-dir set in config: if 'root-dir' in config_tree.node: LOG.warning('You have set "root-dir", which at Cylc 8 does nothing. ' 'See Cylc Install documentation.') # Extract templatevars from the configuration get_rose_vars_from_config_node(config, config_tree.node, os.environ) # Export environment vars for key, val in config['env'].items(): os.environ[key] = val return config
def post_install(srcdir=None, opts=None, rundir=None): if not rose_config_exists(srcdir, opts): return False srcdir, rundir = paths_to_pathlib([srcdir, rundir]) results = {} copy_config_file(srcdir=srcdir, rundir=rundir) results['record_install'] = record_cylc_install_options(srcdir=srcdir, opts=opts, rundir=rundir) results['fileinstall'] = rose_fileinstall(srcdir=srcdir, opts=opts, rundir=rundir) # Finally dump a log of the rose-conf in its final state. if results['fileinstall']: dump_rose_log(rundir=rundir, node=results['fileinstall']) return results
def rose_fileinstall(srcdir=None, opts=None, rundir=None): """Call Rose Fileinstall. Args: srcdir(pathlib.Path): Search for a ``rose-suite.conf`` file in this location. rundir (pathlib.Path) """ if not rose_config_exists(rundir, opts): return False # Load the config tree config_tree = rose_config_tree_loader(rundir, opts) if any(i.startswith('file') for i in config_tree.node.value): try: startpoint = os.getcwd() os.chdir(rundir) except FileNotFoundError as exc: raise exc else: # Carry out imports. from metomi.rose.config_processor import ConfigProcessorsManager from metomi.rose.popen import RosePopener from metomi.rose.reporter import Reporter from metomi.rose.fs_util import FileSystemUtil # Update config tree with install location # NOTE-TO-SELF: value=os.environ["CYLC_WORKFLOW_RUN_DIR"] config_tree.node = config_tree.node.set( keys=["file-install-root"], value=str(rundir) ) # Artificially set rose to verbose. event_handler = Reporter(3) fs_util = FileSystemUtil(event_handler) popen = RosePopener(event_handler) # Process files config_pm = ConfigProcessorsManager(event_handler, popen, fs_util) config_pm(config_tree, "file") finally: os.chdir(startpoint) return config_tree.node
def test_rose_config_exists_true(tmp_path): (tmp_path / "rose-suite.conf").touch() assert rose_config_exists(tmp_path, SimpleNamespace()) is True
def test_rose_config_exists_nonexistant_dir(tmp_path): assert rose_config_exists( tmp_path / "non-existant-folder", SimpleNamespace(opt_conf_keys='', defines=[], rose_template_vars=[])) is False
def test_rose_config_exists_no_rose_suite_conf(tmp_path): assert rose_config_exists( tmp_path, SimpleNamespace(opt_conf_keys=None, defines=[], rose_template_vars=[])) is False
def test_rose_config_exists_conf_set_by_options(tmp_path, opts): assert rose_config_exists( tmp_path, opts, ) is True
def test_rose_config_exists_no_dir(tmp_path): assert rose_config_exists( None, SimpleNamespace(opt_conf_keys=None, defines=[], define_suites=[])) is False