Skip to content

Commit

Permalink
Allow top level settings in CLI Config (#221)
Browse files Browse the repository at this point in the history
allow top level sections in cli config

* Closes #217

---------

Co-authored-by: Ronnie Dutta <[email protected]>
Co-authored-by: Oliver Sanders <[email protected]>
  • Loading branch information
3 people authored Aug 24, 2023
1 parent 6442245 commit 92df362
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 39 deletions.
87 changes: 66 additions & 21 deletions cylc/rose/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from pathlib import Path
import re
import shlex
from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING, Any, List, Tuple, Union

from cylc.flow.hostuserutil import get_host
from cylc.flow import LOG
Expand Down Expand Up @@ -327,6 +327,67 @@ def merge_rose_cylc_suite_install_conf(old, new):
return old


def parse_cli_defines(define: str) -> Union[
bool, Tuple[
List[Union[str, Any]],
Union[str, Any],
Union[str, Any]
]
]:
"""Parse a define string.
Args:
define:
A string in one of two forms:
- `key = "value"`
- `[section]key = "value"`
With optional `!` and `!!` prepended, indicating an ignored state,
which should lead to a warning being logged.
Returns:
False: If state is ignored or trigger-ignored, otherwise...
(keys, value, state)
Examples:
# Top level key
>>> parse_cli_defines('root-dir = "foo"')
(['root-dir'], '"foo"', '')
# Marked as ignored
>>> parse_cli_defines('!root-dir = "foo"')
False
# Inside a section
>>> parse_cli_defines('[section]orange = "segment"')
(['section', 'orange'], '"segment"', '')
"""
match = re.match(
(
r'^\[(?P<section>.*)\](?P<state>!{0,2})'
r'(?P<key>.*)\s*=\s*(?P<value>.*)'
),
define
)
if match:
groupdict = match.groupdict()
keys = [groupdict['section'].strip(), groupdict['key'].strip()]
else:
# Doesn't have a section:
match = re.match(
r'^(?P<state>!{0,2})(?P<key>.*)\s*=\s*(?P<value>.*)', define)
if match and not match['state']:
groupdict = match.groupdict()
keys = [groupdict['key'].strip()]
else:
# This seems like it ought to be an error,
# But behaviour is consistent with Rose 2019
# See: https://github.com/cylc/cylc-rose/issues/217
return False

return (keys, match['value'], match['state'])


def get_cli_opts_node(opts=None, srcdir=None):
"""Create a ConfigNode representing options set on the command line.
Expand Down Expand Up @@ -367,28 +428,12 @@ def get_cli_opts_node(opts=None, srcdir=None):
defines.append(f'[env]ROSE_ORIG_HOST={rose_orig_host}')
rose_template_vars.append(f'ROSE_ORIG_HOST={rose_orig_host}')

# Construct new ouput based on optional Configs:
# Construct new config node representing CLI config items:
newconfig = ConfigNode()

# For each __define__ determine whether it is an env or template define.
for define in defines:
match = re.match(
(
r'^\[(?P<key1>.*)\](?P<state>!{0,2})'
r'(?P<key2>.*)\s*=\s*(?P<value>.*)'
),
define
).groupdict()
if match['key1'] == '' and match['state'] in ['!', '!!']:
LOG.warning(
'CLI opts set to ignored or trigger-ignored will be ignored.'
)
else:
newconfig.set(
keys=[match['key1'], match['key2']],
value=match['value'],
state=match['state']
)
parsed_define = parse_cli_defines(define)
if parsed_define:
newconfig.set(*parsed_define)

# For each __suite define__ add define.
if srcdir is not None:
Expand Down
18 changes: 0 additions & 18 deletions tests/unit/test_config_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,24 +467,6 @@ def test_merge_opts(
assert merge_opts(conf, opt_conf_keys) == expected


@pytest.mark.parametrize(
'state',
['!', '!!']
)
def test_cli_defines_ignored_are_ignored(
state, caplog
):
opts = SimpleNamespace(
opt_confs='', defines=[f'[]{state}opts=ignore me'],
rose_template_vars=[]
)

get_cli_opts_node(opts)
assert (caplog.records[0].message ==
'CLI opts set to ignored or trigger-ignored will be ignored.'
)


@pytest.mark.parametrize(
'opt_confs, defines, rose_template_vars, expect',
[
Expand Down

0 comments on commit 92df362

Please sign in to comment.