Skip to content

Commit

Permalink
Merge pull request #6475 from wxtim/feature.commas-in-install_target_…
Browse files Browse the repository at this point in the history
…sections

Expand comma separated lists in `global.cylc:[install][symlink dirs]`
  • Loading branch information
hjoliver authored Nov 25, 2024
2 parents 443112e + bebfe1f commit 9f06bb8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 13 deletions.
1 change: 1 addition & 0 deletions changes.d/6475.feat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow easy definition of multiple install targets in `global.cylc[install][symlink dirs]` using comma separated lists.
73 changes: 64 additions & 9 deletions cylc/flow/cfgspec/globalcfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import os
from pathlib import Path
from sys import stderr
from textwrap import dedent
from textwrap import dedent, indent
from typing import List, Optional, Tuple, Any, Union

from contextlib import suppress
Expand Down Expand Up @@ -588,6 +588,47 @@
'''
}


def comma_sep_section_note(version_changed: str = '') -> str:
note_text = "This section can be a comma separated list."
if version_changed:
note_text = (
f".. versionchanged:: {version_changed}\n\n" +
indent(note_text, 3 * ' ')
)

example = dedent('''
.. spoiler:: Example
For example:
.. code-block:: cylc
[a, b]
setting = x
[a]
another_setting = y
Will become:
.. code-block:: cylc
[a]
setting = x
[b]
setting = x
[a]
another_setting = y
Which will then be combined according to
:ref:`the rules for Cylc config syntax<syntax>`.
''')

return "\n\n.. note::\n\n" + indent(note_text + example, 3 * ' ')


# ----------------------------------------------------------------------------


Expand Down Expand Up @@ -1132,9 +1173,12 @@ def default_for(
.. versionadded:: 8.0.0
"""):
with Conf('<install target>', desc="""
with Conf('<install target>', desc=dedent("""
:ref:`Host <Install targets>` on which to create the symlinks.
"""):
.. versionadded:: 8.0.0
""") + comma_sep_section_note(version_changed='8.4.0')):
Conf('run', VDR.V_STRING, None, desc="""
Alternative location for the run dir.
Expand Down Expand Up @@ -1176,7 +1220,9 @@ def default_for(
.. versionadded:: 8.0.0
'''):
with Conf('<platform name>', desc='''
with Conf(
'<platform name>',
desc=dedent('''
Configuration defining a platform.
Many of these settings have replaced those of the same name from
Expand Down Expand Up @@ -1220,8 +1266,10 @@ def default_for(
- :ref:`AdminGuide.PlatformConfigs`, an administrator's guide to
platform configurations.
.. versionadded:: 8.0.0
''') as Platform:
''')
+ comma_sep_section_note()
+ ".. versionadded:: 8.0.0",
) as Platform:
with Conf('meta', desc=PLATFORM_META_DESCR):
Conf('<custom metadata>', VDR.V_STRING, '', desc='''
Any user-defined metadata item.
Expand Down Expand Up @@ -1987,6 +2035,7 @@ def load(self) -> None:
self.dense.clear()
LOG.debug("Loading site/user config files")
conf_path_str = os.getenv("CYLC_CONF_PATH")

if conf_path_str:
# Explicit config file override.
fname = os.path.join(conf_path_str, self.CONF_BASENAME)
Expand All @@ -1999,7 +2048,7 @@ def load(self) -> None:

# Expand platforms needs to be performed first because it
# manipulates the sparse config.
self._expand_platforms()
self._expand_commas()

# Flesh out with defaults
self.expand()
Expand Down Expand Up @@ -2043,8 +2092,8 @@ def _no_platform_group_name_overlap(self):
msg += f'\n * {name}'
raise GlobalConfigError(msg)

def _expand_platforms(self):
"""Expand comma separated platform names.
def _expand_commas(self):
"""Expand comma separated section headers.
E.G. turn [platforms][foo, bar] into [platforms][foo] and
platforms[bar].
Expand All @@ -2053,6 +2102,12 @@ def _expand_platforms(self):
self.sparse['platforms'] = expand_many_section(
self.sparse['platforms']
)
if (
self.sparse.get("install", {}).get("symlink dirs")
):
self.sparse["install"]["symlink dirs"] = expand_many_section(
self.sparse["install"]["symlink dirs"]
)

def platform_dump(
self,
Expand Down
24 changes: 20 additions & 4 deletions tests/unit/cfgspec/test_globalcfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,19 @@ def test_dump_platform_details(capsys, mock_global_config):
assert expected == out


def test_expand_platforms(tmp_path: Path, mock_global_config: Callable):
"""It should expand comma separated platform definitions."""
def test_expand_commas(tmp_path: Path, mock_global_config: Callable):
"""It should expand comma separated platform and install target
definitions."""
glblcfg: GlobalConfig = mock_global_config('''
[install]
[[symlink dirs]]
[[[foo, bar]]]
run = /x
[[[foo]]]
share = /y
[[[bar]]]
share = /z
[platforms]
[[foo]]
[[[meta]]]
Expand All @@ -91,7 +101,7 @@ def test_expand_platforms(tmp_path: Path, mock_global_config: Callable):
[[[meta]]]
x = 4
''')
glblcfg._expand_platforms()
glblcfg._expand_commas()

# ensure the definition order is preserved
assert glblcfg.get(['platforms']).keys() == [
Expand All @@ -102,12 +112,18 @@ def test_expand_platforms(tmp_path: Path, mock_global_config: Callable):
'pub',
]

# ensure sections are correctly deep-merged
# ensure platform sections are correctly deep-merged
assert glblcfg.get(['platforms', 'foo', 'meta', 'x']) == '1'
assert glblcfg.get(['platforms', 'bar', 'meta', 'x']) == '3'
assert glblcfg.get(['platforms', 'baz', 'meta', 'x']) == '3'
assert glblcfg.get(['platforms', 'pub', 'meta', 'x']) == '4'

# ensure install target sections are correctly merged:
assert glblcfg.get(["install", "symlink dirs", "foo", "run"]) == "/x"
assert glblcfg.get(["install", "symlink dirs", "foo", "share"]) == "/y"
assert glblcfg.get(["install", "symlink dirs", "bar", "run"]) == "/x"
assert glblcfg.get(["install", "symlink dirs", "bar", "share"]) == "/z"


@pytest.mark.parametrize(
'src_dir, err_expected',
Expand Down

0 comments on commit 9f06bb8

Please sign in to comment.