From f1b8ea81cb857de550bbbd02a07c6d8bfa9867c8 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Tue, 30 Sep 2025 21:54:47 +0200 Subject: [PATCH] feat: family or dynamic could needs type attribute --- src/rougail/output_formatter/__init__.py | 46 +++++++++++++++++-- .../rougail/00-base.yml | 13 ++++++ .../rougail/00-base.yml | 9 ++++ tests/test_load.py | 2 +- 4 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 tests/results/20_2family_looks_like_dynamic/rougail/00-base.yml create mode 100644 tests/results/20_2family_looks_like_variable/rougail/00-base.yml diff --git a/src/rougail/output_formatter/__init__.py b/src/rougail/output_formatter/__init__.py index b0210de..6a4f29d 100644 --- a/src/rougail/output_formatter/__init__.py +++ b/src/rougail/output_formatter/__init__.py @@ -77,6 +77,18 @@ RoundTripRepresenter.add_representer(str, represent_str) # XXX +class RougailConvertFormatter(RougailConvert): + def parse_root_file( + self, + filename: str, + path: str, + version: str, + objects: dict, + ) -> None: + self.objects = objects + super().parse_root_file(filename, path, version, objects) + + class RougailOutputFormatter: output_name = "formatter" @@ -161,7 +173,7 @@ class RougailOutputFormatter: filename ) self.version_name, datas = RougailUpgrade(self.rougailconfig).run(filename) - self.rougail = RougailConvert(self.rougailconfig) + self.rougail = RougailConvertFormatter(self.rougailconfig) self.rougail.load_config() self.rougail.init() self.filename_str = str(filename) @@ -239,10 +251,36 @@ class RougailOutputFormatter: attr = f"_{attr}" family[attr] = self.object_to_yaml(attr, type_, value, False, path) if type_ == "dynamic" or (children and type_ == "family"): - if "_type" in family: - del family["_type"] + tmp_family = family.copy() + if "_type" in tmp_family: + del tmp_family["_type"] else: - del family["type"] + del tmp_family["type"] + for child_path in self.rougail.parents[path]: + child = self.rougail.objects + if self.rougail.has_namespace: + split_path = child_path.split('.')[1:] + else: + split_path = child_path.split('.') + for cpath in split_path: + if cpath not in child and '{{ identifier }}' in cpath: + # support format 1.0 + if cpath.replace('{{ identifier }}', '') in child: + cpath = cpath.replace('{{ identifier }}', '') + elif cpath.replace('{{ identifier }}', '{{ suffix }}') in child: + cpath = cpath.replace('{{ identifier }}', '{{ suffix }}') + child = child[cpath] + tmp_family[cpath] = child + family_type = self.rougail.is_family_or_variable("", tmp_family, False, "") + if family_type == "family": + family_type = self.rougail.get_family_or_variable_type(tmp_family) + if family_type is None: + family_type = 'family' + if family_type == type_: + if "_type" in family: + del family["_type"] + else: + del family["type"] if not set(family): ret[name] = CommentedMap() ret.yaml_value_comment_extend( diff --git a/tests/results/20_2family_looks_like_dynamic/rougail/00-base.yml b/tests/results/20_2family_looks_like_dynamic/rougail/00-base.yml new file mode 100644 index 0000000..435659a --- /dev/null +++ b/tests/results/20_2family_looks_like_dynamic/rougail/00-base.yml @@ -0,0 +1,13 @@ +%YAML 1.2 +--- +version: 1.1 + +my_family: + type: family + + dynamic: + - val1 + - val2 + + var: true # a variable +... diff --git a/tests/results/20_2family_looks_like_variable/rougail/00-base.yml b/tests/results/20_2family_looks_like_variable/rougail/00-base.yml new file mode 100644 index 0000000..2e14177 --- /dev/null +++ b/tests/results/20_2family_looks_like_variable/rougail/00-base.yml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +version: 1.1 + +my_family: + type: family + + default: true +... diff --git a/tests/test_load.py b/tests/test_load.py index fb0bfdc..c28e4ea 100644 --- a/tests/test_load.py +++ b/tests/test_load.py @@ -15,7 +15,7 @@ excludes = [ ] test_ok = get_structures_list(excludes) -# test_ok = [Path('../rougail-tests/structures/40_2leadership_calculation_index')] +# test_ok = [Path('../rougail-tests/structures/60_6family_dynamic_sub_dynamic_1_0_2')] def idfn(fixture_value):