"""Update Rougail structure file to new version Cadoles (http://www.cadoles.com) Copyright (C) 2021 Silique (https://www.silique.fr) Copyright (C) 2022-2025 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . """ from ruamel.yaml import YAML, CommentedMap from rougail import RougailConfig VERSIONS = ["1.0", "1.1"] def get_function_name(version): version = version.replace(".", "_") return f"update_{version}" FUNCTION_VERSIONS = [(version, get_function_name(version)) for version in VERSIONS] class RougailUpgrade: def __init__( self, rougailconfig: RougailConfig = None, ) -> None: self.rougailconfig = rougailconfig def run( self, file: str, ) -> dict: with file.open() as file_fh: root = YAML().load(file_fh) if not root: root = {} if "_version" in root: version_name = "_version" format_version = str(root.pop("_version")) elif "version" in root: version_name = "version" format_version = str(root.pop("version")) else: version_name = None format_version = self.rougailconfig["default_structural_format_version"] if format_version not in VERSIONS: raise Exception(f'version "{format_version}" is not a valid version') search_function_name = get_function_name(format_version) function_found = False for version, function_version in FUNCTION_VERSIONS: if function_found and hasattr(self, function_version): root = getattr(self, function_version)(root) if function_version == search_function_name: function_found = True if version_name: root[version_name] = float(version) return version_name, root def update_1_1( self, root, ): new_root = CommentedMap() for key, value in root.items(): if not isinstance(value, dict): if key == "variable" and "{{ suffix }}" in value: value = value.replace("{{ suffix }}", "{{ identifier }}") new_root[key] = value continue # migrate dynamic family if ( ("variable" in value and isinstance(value["variable"], str)) or ("_variable" in value and isinstance(value["_variable"], str)) ) and ( ("_type" in value and value["_type"] == "dynamic") or ("type" in value and value["type"] == "dynamic") ): value["dynamic"] = { "type": "variable", "variable": value.pop("variable"), "propertyerror": False, } if "{{ suffix }}" in key: key = key.replace("{{ suffix }}", "{{ identifier }}") elif "{{ identifier }}" not in key: key = key + "{{ identifier }}" value = self.update_1_1(value) new_root[key] = value for typ, obj in { "boolean": bool, "integer": int, "string": str, "float": float, }.items(): if value.get("type") == typ: default = value.get("default") if default is None or default == []: continue if isinstance(default, obj): del value["type"] elif isinstance(default, list) and isinstance(default[0], obj): del value["type"] if value.get("multi") and isinstance(value.get("default"), list): del value["multi"] return new_root