From 4d3d742a68271547926c7ea540b8db13c49cf676 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Tue, 13 May 2025 21:42:54 +0200 Subject: [PATCH] feat: yaml.filename could be the name of a directory --- src/rougail/user_data_yaml/__init__.py | 81 ++++++++++++++------------ src/rougail/user_data_yaml/config.py | 2 - tests/test_load.py | 29 ++++++++- 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/rougail/user_data_yaml/__init__.py b/src/rougail/user_data_yaml/__init__.py index 9822a29..ed5ff47 100644 --- a/src/rougail/user_data_yaml/__init__.py +++ b/src/rougail/user_data_yaml/__init__.py @@ -17,6 +17,7 @@ along with this program. If not, see . """ from ruamel.yaml import YAML +from pathlib import Path from rougail.error import ExtentionError from tiramisu.error import ValueOptionError, PropertiesOptionError, LeadershipError @@ -56,48 +57,54 @@ class RougailUserDataYaml: self.yaml = YAML() user_datas = [] for idx, filename in enumerate(self.filenames): - file_values = self.open(filename) - if not file_values: - continue - values = {} - if not isinstance(file_values, dict): - self.errors.append( - _( - 'cannot load "{0}", the root value is not a dict but "{1}"' - ).format(filename, file_values) - ) + filename = Path(filename) + if filename.is_file(): + filenames = [filename] else: - self.parse( - values, - "", - file_values, - filename, + filenames = list(filename.glob('*.yml')) + list(filename.glob('*.yaml')) + for filename in sorted(filenames): + file_values = self.open(filename) + if not file_values: + continue + values = {} + if not isinstance(file_values, dict): + self.errors.append( + _( + 'cannot load "{0}", the root value is not a dict but "{1}"' + ).format(filename, file_values) + ) + else: + self.parse( + values, + "", + file_values, + filename, + ) + if self.file_with_secrets == "none": + allow_secrets_variables = False + elif self.file_with_secrets == "first": + allow_secrets_variables = idx == 0 + elif self.file_with_secrets == "last": + if not idx: + last_filenames = len(self.filenames) - 1 + allow_secrets_variables = idx == last_filenames + else: + allow_secrets_variables = True + user_datas.append( + { + "source": _('the YAML file "{0}"').format(filename), + "errors": self.errors, + "warnings": self.warnings, + "values": values, + "options": { + "allow_secrets_variables": allow_secrets_variables, + }, + } ) - if self.file_with_secrets == "none": - allow_secrets_variables = False - elif self.file_with_secrets == "first": - allow_secrets_variables = idx == 0 - elif self.file_with_secrets == "last": - if not idx: - last_filenames = len(self.filenames) - 1 - allow_secrets_variables = idx == last_filenames - else: - allow_secrets_variables = True - user_datas.append( - { - "source": _('the YAML file "{0}"').format(filename), - "errors": self.errors, - "warnings": self.warnings, - "values": values, - "options": { - "allow_secrets_variables": allow_secrets_variables, - }, - } - ) return user_datas def open(self, filename: str) -> dict: - with open(filename) as fh_config: + with filename.open() as fh_config: return self.yaml.load(fh_config) def parse( diff --git a/src/rougail/user_data_yaml/config.py b/src/rougail/user_data_yaml/config.py index 584954c..23d8672 100644 --- a/src/rougail/user_data_yaml/config.py +++ b/src/rougail/user_data_yaml/config.py @@ -43,8 +43,6 @@ yaml: params: allow_relative: True test_existence: True - types: - - file file_with_secrets: description: {_("File that may contain secrets")} diff --git a/tests/test_load.py b/tests/test_load.py index 898f6b0..f2d6389 100644 --- a/tests/test_load.py +++ b/tests/test_load.py @@ -163,11 +163,11 @@ def test_errors_2(): ####################################################################### -error_env = list((Path(__file__).parent / 'errors' / 'yaml').glob("*.yaml")) -error_env.sort() +error_yaml = list((Path(__file__).parent / 'errors' / 'yaml').glob("*.yaml")) +error_yaml.sort() -@fixture(scope="module", params=error_env, ids=idfn) +@fixture(scope="module", params=error_yaml, ids=idfn) def test_file_error(request): return request.param @@ -191,3 +191,26 @@ def test_dictionaries_error(test_file_error): with open(errors_file) as json_file: expected_errors = load(json_file) assert expected_errors == errors, errors_file + + +def test_dictionaries_directory(): + test_dir = Path(__file__).parent / 'directory' + rougailconfig = get_rougail_config(test_dir / 'structure') + ################################## + rougailconfig['step.user_data'] = ['yaml'] + rougailconfig['yaml.filename'] = [str(test_dir / 'yaml')] + rougail = Rougail(rougailconfig) + config = rougail.run() + ################################## + # loads variables in the tiramisu config + generated_user_data = RougailUserData(config, rougailconfig=rougailconfig).run() + rougail.user_datas(generated_user_data) + config.property.read_only() + data = dict(config_to_dict(config.value.get())) + data_file = test_dir / "result.txt" + if not data_file.is_file(): + with open(data_file, 'a') as json_file: + dump(data, json_file, indent=4) + with open(data_file) as json_file: + expected = load(json_file) + assert expected == data, data_file