diff --git a/src/rougail/annotator/__init__.py b/src/rougail/annotator/__init__.py index d9b17faf3..2f4fd184d 100644 --- a/src/rougail/annotator/__init__.py +++ b/src/rougail/annotator/__init__.py @@ -84,13 +84,17 @@ class SpaceAnnotator: # pylint: disable=R0903 for extra_annotator in objectspace.rougailconfig['extra_annotators']: annotators.extend(ANNOTATORS[extra_annotator]) annotators = sorted(annotators, key=get_level) - functions = [] + functions = {} functions_files = objectspace.rougailconfig['functions_file'] if not isinstance(functions_files, list): functions_files = [functions_files] for functions_file in functions_files: if isfile(functions_file): - functions.extend(dir(load_modules(functions_file))) + loaded_modules = load_modules(functions_file) + for function in dir(loaded_modules): + if function.startswith('_'): + continue + functions[function] = getattr(loaded_modules, function) for annotator in annotators: annotator(objectspace, functions, diff --git a/src/rougail/annotator/check.py b/src/rougail/annotator/check.py index d18a30a40..a1b44c4b5 100644 --- a/src/rougail/annotator/check.py +++ b/src/rougail/annotator/check.py @@ -48,6 +48,7 @@ class Annotator(TargetAnnotator, ParamAnnotator): functions, *args, ): + return self.objectspace = objectspace self.only_variable = True self.target_is_uniq = False diff --git a/src/rougail/annotator/condition.py b/src/rougail/annotator/condition.py index 6b2a5d84c..0b9cb0e97 100644 --- a/src/rougail/annotator/condition.py +++ b/src/rougail/annotator/condition.py @@ -52,24 +52,25 @@ class Annotator(TargetAnnotator, ParamAnnotator, Walk): *args, ): self.objectspace = objectspace - self.target_is_uniq = False - self.only_variable = False - self.allow_function = False - self.force_service_value = {} - if hasattr(objectspace.space, 'variables'): +# self.target_is_uniq = False +# self.only_variable = False +# self.allow_function = False +# self.force_service_value = {} + if self.objectspace.paths: + print('ah ahhhhhhhh') self.convert_auto_freeze() - for path_prefix, constraints in self.get_constraints(): - if not hasattr(constraints, 'condition'): - continue - self.convert_target(constraints.condition, path_prefix) - self.check_condition_optional(constraints, path_prefix) - self.convert_condition_source(constraints, path_prefix) - self.convert_param(constraints.condition, path_prefix) - self.check_source_target(constraints) - self.convert_xxxlist(constraints, path_prefix) - self.check_choice_option_condition(constraints, path_prefix) - self.remove_condition_with_empty_target(constraints) - self.convert_condition(constraints, path_prefix) + #for path_prefix, constraints in self.get_constraints(): + # if not hasattr(constraints, 'condition'): + # continue + # self.convert_target(constraints.condition, path_prefix) + # self.check_condition_optional(constraints, path_prefix) + # self.convert_condition_source(constraints, path_prefix) + # self.convert_param(constraints.condition, path_prefix) + # self.check_source_target(constraints) + # self.convert_xxxlist(constraints, path_prefix) + # self.check_choice_option_condition(constraints, path_prefix) + # self.remove_condition_with_empty_target(constraints) + # self.convert_condition(constraints, path_prefix) def valid_type_validation(self, obj, @@ -83,12 +84,14 @@ class Annotator(TargetAnnotator, ParamAnnotator, Walk): only if auto_freeze_variable is True this variable is frozen """ for variable in self.get_variables(): + print(variable.auto_freeze, variable.auto_save) if not variable.auto_freeze and not variable.auto_save: continue + print('pffff') #if variable.namespace != self.objectspace.rougailconfig['variable_namespace']: # msg = _(f'auto_freeze is not allowed in extra "{variable.namespace}"') # raise DictConsistencyError(msg, 49, variable.xmlfiles) - variable.force_store_value = True + self.objectspace.properties.append(variable.path, 'force_store_value') if variable.auto_save: continue auto_freeze_variable = self.objectspace.rougailconfig['auto_freeze_variable'] diff --git a/src/rougail/annotator/family.py b/src/rougail/annotator/family.py index 9ea37148c..046934991 100644 --- a/src/rougail/annotator/family.py +++ b/src/rougail/annotator/family.py @@ -54,8 +54,9 @@ class Annotator(Walk): objectspace, *args, ): + self.mode_auto = [] self.objectspace = objectspace - if not hasattr(self.objectspace.space, 'variables'): + if not self.objectspace.paths: return self.modes = {name: Mode(idx) for idx, name in enumerate(self.objectspace.rougailconfig['modes_level'])} self.remove_empty_families() @@ -68,9 +69,9 @@ class Annotator(Walk): """Remove all families without any variable """ removed_families = {} - for family, parent in self.get_families(with_parent=True): - if isinstance(family, self.objectspace.family) and not self._has_variable(family): - removed_families.setdefault(parent, []).append(family) +# for family in self.get_families(): +# if isinstance(family, self.objectspace.family) and not self._has_variable(family): +# removed_families.setdefault(parent, []).append(family) for parent, families in removed_families.items(): for family in families: del parent.variable[family.name] @@ -91,10 +92,10 @@ class Annotator(Walk): """Set doc, path, ... to family """ for family in self.get_families(): - if not hasattr(family, 'description'): + if not family.description: family.description = family.name - family.doc = family.description - del family.description +# family.doc = family.description +# del family.description def change_modes(self): """change the mode of variables @@ -130,17 +131,21 @@ class Annotator(Walk): def _set_default_mode(self, family: 'self.objectspace.family', ) -> None: - if not hasattr(family, 'variable'): + children = self.objectspace.parents[family.path] + if not children: return if self._has_mode(family): family_mode = family.mode else: family_mode = None leader = None - for variable in family.variable.values(): + for variable_path in children: + variable = self.objectspace.paths[variable_path] + if variable.type == 'symlink': + continue if leader is None and hasattr(family, 'leadership') and family.leadership: leader = variable - if isinstance(variable, self.objectspace.family): + if variable_path in self.objectspace.families: # set default mode a subfamily if family_mode and not self._has_mode(variable): self._set_auto_mode(variable, family_mode) @@ -154,9 +159,8 @@ class Annotator(Walk): # here because follower can change leader mode self._set_auto_mode(family, leader.mode) - @staticmethod - def _has_mode(obj) -> bool: - return 'mode' in vars(obj) and not hasattr(obj, 'mode_auto') + def _has_mode(self, obj) -> bool: + return obj.mode and not obj.path in self.mode_auto def _set_default_mode_variable(self, variable: 'self.objectspace.variable', @@ -176,10 +180,12 @@ class Annotator(Walk): elif family_mode and not self._has_mode(variable): self._set_auto_mode(variable, family_mode) - @staticmethod - def _set_auto_mode(obj, mode: str) -> None: + def _set_auto_mode(self, + obj, + mode: str, + ) -> None: obj.mode = mode - obj.mode_auto = True + self.mode_auto.append(obj.path) def _set_default_mode_leader(self, leader: 'self.objectspace.variable', @@ -215,16 +221,19 @@ class Annotator(Walk): def _change_family_mode(self, family: 'self.objectspace.family', ) -> None: - if hasattr(family, 'mode'): + if family.mode: family_mode = family.mode else: family_mode = self.objectspace.rougailconfig['default_family_mode'] min_variable_mode = self.objectspace.rougailconfig['modes_level'][-1] # change variable mode, but not if variables are not in a family - is_leadership = hasattr(family, 'leadership') and family.leadership - if hasattr(family, 'variable'): - for idx, variable in enumerate(family.variable.values()): - if isinstance(variable, self.objectspace.family): + is_leadership = family.type == 'leadership' + if family.path in self.objectspace.parents: + for idx, variable_path in enumerate(self.objectspace.parents[family.path]): + variable = self.objectspace.paths[variable_path] + if variable.type == 'symlink': + continue + if variable_path in self.objectspace.families: if not hasattr(variable, 'mode'): variable.mode = self.objectspace.rougailconfig['default_family_mode'] #elif idx == 0 and is_leadership: @@ -236,23 +245,23 @@ class Annotator(Walk): self._change_variable_mode(variable, family_mode, is_leadership) if self.modes[min_variable_mode] > self.modes[variable.mode]: min_variable_mode = variable.mode - if not isinstance(family, (self.objectspace.family, self.objectspace.variables)): - # it's Variable, Service, ... - return - if not hasattr(family, 'mode'): +#FIXME if not isinstance(family, (self.objectspace.family, self.objectspace.variables)): +# # it's Variable, Service, ... +# return + if not family.mode: # set the lower variable mode to family self._set_auto_mode(family, min_variable_mode) - if not is_leadership and family.mode != min_variable_mode: - msg = _(f'the family "{family.name}" is in "{family.mode}" mode but variables and ' - f'families inside have the higher modes "{min_variable_mode}"') - raise DictConsistencyError(msg, 62, family.xmlfiles) +#FIXME if not is_leadership and family.mode != min_variable_mode: +#FIXME msg = _(f'the family "{family.name}" is in "{family.mode}" mode but variables and ' +#FIXME f'families inside have the higher modes "{min_variable_mode}"') +#FIXME raise DictConsistencyError(msg, 62, family.xmlfiles) def _change_variable_mode(self, variable, family_mode: str, is_follower: bool, ) -> None: - if hasattr(variable, 'mode'): + if variable.mode: variable_mode = variable.mode else: variable_mode = self.objectspace.rougailconfig['default_variable_mode'] @@ -263,7 +272,7 @@ class Annotator(Walk): f'but family has the higher family mode "{family_mode}"') raise DictConsistencyError(msg, 61, variable.xmlfiles) self._set_auto_mode(variable, family_mode) - if not hasattr(variable, 'mode'): + if not variable.mode: variable.mode = variable_mode def dynamic_families(self): @@ -293,9 +302,7 @@ class Annotator(Walk): """Convert variable help """ for family in self.get_families(): - if not hasattr(family, 'help'): + if not family.help: continue - if not hasattr(family, 'information'): - family.information = self.objectspace.information(family.xmlfiles) - family.information.help = family.help + self.objectspace.informations.add(family.path, 'help', family.help) del family.help diff --git a/src/rougail/annotator/fill.py b/src/rougail/annotator/fill.py index 46eb8e875..8822fb8e3 100644 --- a/src/rougail/annotator/fill.py +++ b/src/rougail/annotator/fill.py @@ -67,42 +67,44 @@ class CollectUndefined(Undefined): def get_jinja_variable_to_param(jinja_text, objectspace, - obj, + xmlfiles, path_prefix, + functions, variable_name, variable_path, ): CollectUndefined.variables = set() try: - SandboxedEnvironment(loader=DictLoader({'tmpl': jinja_text}), undefined=CollectUndefined).get_template('tmpl').render() + SandboxedEnvironment(loader=DictLoader({'tmpl': jinja_text}), undefined=CollectUndefined).get_template('tmpl').render(**functions) except UndefinedError as err: msg = _(f'error in jinja "{jinja_text}": {err}') - raise DictConsistencyError(msg, 91, obj.xmlfiles) from err + raise DictConsistencyError(msg, 91, xmlfiles) from err variables = list(CollectUndefined.variables) variables.sort() for variable in variables: - new_param = objectspace.param(obj.xmlfiles) - if variable in [variable_name, variable_path]: - new_param.name = '__internal_key' - new_param.type = 'string' - new_param.text = variable - else: - new_param.name = variable - new_param.text = variable - try: - set_variable_to_param(new_param, - objectspace, - None, - obj.namespace, - path_prefix, - None, - ) - except DictConsistencyError as err: - if err.errno != 42: - raise err from err - continue - new_param.type = 'variable' - obj.param.append(new_param) + #new_param = objectspace.param(obj.xmlfiles) + #if variable in [variable_name, variable_path]: + # new_param.name = '__internal_key' + # new_param.type = 'string' + # new_param.text = variable + #else: + yield objectspace.paths[variable] + #new_param.name = variable + #new_param.text = variable + #try: + # set_variable_to_param(new_param, + # objectspace, + # None, + # obj.namespace, + # path_prefix, + # None, + # ) + #except DictConsistencyError as err: + # if err.errno != 42: + # raise err from err + # continue + #new_param.type = 'variable' + #obj.param.append(new_param) CALC_MULTI = ('calc_value', @@ -130,6 +132,7 @@ class Annotator(TargetAnnotator, ParamAnnotator): functions, *args, ): + return self.objectspace = objectspace self.functions = copy(functions) self.functions.extend(self.objectspace.rougailconfig['internal_functions']) diff --git a/src/rougail/annotator/group.py b/src/rougail/annotator/group.py index e0262d060..c4a449ccc 100644 --- a/src/rougail/annotator/group.py +++ b/src/rougail/annotator/group.py @@ -41,7 +41,7 @@ class Annotator(Walk): objectspace, *args, ): - if not hasattr(objectspace.space, 'variables'): + if not objectspace.paths: return self.objectspace = objectspace self.convert_groups() @@ -51,9 +51,7 @@ class Annotator(Walk): """ # store old leaders family name for family in self.get_families(): - if not isinstance(family, self.objectspace.family): - continue - if not family.leadership: + if family.type != 'leadership': continue if hasattr(family, 'dynamic'): msg = _(f'the family "{family.name}" cannot be leadership and dynamic together') diff --git a/src/rougail/annotator/property.py b/src/rougail/annotator/property.py index 5b618dcd4..04926c67e 100644 --- a/src/rougail/annotator/property.py +++ b/src/rougail/annotator/property.py @@ -45,88 +45,85 @@ class Annotator(Walk): *args ) -> None: self.objectspace = objectspace - services = [] - if not self.objectspace.paths.has_path_prefix() and hasattr(self.objectspace.space, 'services'): - services.append(self.objectspace.space.services) - elif hasattr(self.objectspace.space, 'variables'): - for path_prefix in self.objectspace.paths.get_path_prefixes(): - if path_prefix in self.objectspace.space.variables and \ - hasattr(self.objectspace.space.variables[path_prefix], 'services'): - services.append(self.objectspace.space.variables[path_prefix].services) - for service in services: - self.convert_services(service) - if hasattr(self.objectspace.space, 'variables'): +# services = [] +# if not self.objectspace.paths.has_path_prefix() and hasattr(self.objectspace.space, 'services'): +# services.append(self.objectspace.space.services) +# elif hasattr(self.objectspace.space, 'variables'): +# for path_prefix in self.objectspace.paths.get_path_prefixes(): +# if path_prefix in self.objectspace.space.variables and \ +# hasattr(self.objectspace.space.variables[path_prefix], 'services'): +# services.append(self.objectspace.space.variables[path_prefix].services) + if self.objectspace.paths: + for family in self.get_families(): + #if family.path != 'services' and not family.path.startswith('services.'): + if family.path != 'services': + continue + self.convert_services(family) self.convert_family() self.convert_variable() - def convert_property(self, - variable, - ) -> None: - """convert properties - """ - # hidden variable is also frozen - if isinstance(variable, self.objectspace.variable) and variable.hidden is True and \ - variable.name != self.objectspace.rougailconfig['auto_freeze_variable']: - if not variable.auto_freeze and \ - not hasattr(variable, 'provider') and not hasattr(variable, 'supplier'): - variable.frozen = True - if not variable.auto_save and \ - not variable.auto_freeze and \ - 'force_default_on_freeze' not in vars(variable) and \ - not hasattr(variable, 'provider') and not hasattr(variable, 'supplier'): - variable.force_default_on_freeze = True - if not hasattr(variable, 'properties'): - variable.properties = [] - if 'mandatory' in vars(variable) and not variable.mandatory and variable.multi: - # a multi could not have "None" has value - # to permit it, just add mandatory="False" - variable.properties.append('notempty') - for prop in PROPERTIES: - if hasattr(variable, prop): - if getattr(variable, prop) is True: -# for subprop in CONVERT_PROPERTIES.get(prop, [prop]): - variable.properties.append(prop) - setattr(variable, prop, None) - if hasattr(variable, 'unique') and variable.unique != 'nil': - if variable.unique == 'False' or variable.unique is False: - variable.properties.append('notunique') - else: - variable.properties.append('unique') - if hasattr(variable, 'mode') and variable.mode: - variable.properties.append(variable.mode) - variable.mode = None - if 'force_store_value' in variable.properties and \ - 'force_default_on_freeze' in variable.properties: # pragma: no cover - # should not appened - msg = _('cannot have auto_freeze or auto_save with the hidden ' - f'variable "{variable.name}"') - raise DictConsistencyError(msg, 50, variable.xmlfiles) - if not variable.properties: - del variable.properties - def convert_services(self, services) -> None: """convert services """ - self.convert_property(services) - for services_ in services.service.values(): - self.convert_property(services_) - for service in vars(services_).values(): - if not isinstance(service, self.objectspace.family): - continue - self.convert_property(service) - for family in service.family: - self.convert_property(family) - for variable in family.variable: - self.convert_property(variable) + self._convert_property(services) def convert_family(self) -> None: """convert families """ for family in self.get_families(): - self.convert_property(family) + if family.path == 'services' or family.path.startswith('services.'): + continue + self._convert_property(family) def convert_variable(self) -> None: """convert variables """ for variable in self.get_variables(): - self.convert_property(variable) + if variable.path.startswith('services.'): + continue + if variable.type == 'symlink': + continue + self._convert_variable_property(variable) + + def _convert_variable_property(self, + variable: dict, + ) -> None: + """convert properties + """ + path = variable.path + # hidden variable is also frozen + if variable.hidden is True and variable.name != self.objectspace.rougailconfig['auto_freeze_variable']: + if not variable.auto_freeze and \ + variable.provider is None and \ + variable.supplier is None: + self.objectspace.properties.append(variable.path, 'frozen') + if not variable.auto_save and \ + not variable.auto_freeze and \ + 'force_default_on_freeze' not in self.objectspace.properties[path] and \ + variable.provider is None and variable.supplier is None: + self.objectspace.properties.append(path, 'force_default_on_freeze') + if not variable.mandatory and variable.multi: + # a multi could not have "None" has value + # to permit it, just add mandatory="False" + self.objectspace.properties.append(path, 'notempty') + if variable.unique is not None: + if variable.unique is False: + self.objectspace.properties.append(path, 'notunique') + else: + self.objectspace.properties.append(path, 'unique') + if 'force_store_value' in self.objectspace.properties[path] and \ + 'force_default_on_freeze' in self.objectspace.properties[path]: # pragma: no cover + # should not appened + msg = _('cannot have auto_freeze or auto_save with the hidden ' + f'variable "{variable.name}"') + raise DictConsistencyError(msg, 50, variable.xmlfiles) + self._convert_property(variable) + + def _convert_property(self, + obj: dict, + ) -> None: + for prop in PROPERTIES: + if hasattr(obj, prop) and getattr(obj, prop) is True: + self.objectspace.properties.append(obj.path, prop) + if obj.mode: + self.objectspace.properties.append(obj.path, obj.mode) diff --git a/src/rougail/annotator/service.py b/src/rougail/annotator/service.py index ce0829da5..565cdc775 100644 --- a/src/rougail/annotator/service.py +++ b/src/rougail/annotator/service.py @@ -48,13 +48,6 @@ FORCE_INFORMATIONS = ['mode'] class Annotator: """Manage service's object - for example:: - - - - - - """ level = 20 def __init__(self, @@ -63,108 +56,147 @@ class Annotator: ) -> None: self.objectspace = objectspace self.uniq_overrides = {} - if 'network_type' not in self.objectspace.types: - self.objectspace.types['network_type'] = self.objectspace.types['ip_type'] + #if 'network_type' not in self.objectspace.types: + # self.objectspace.types['network_type'] = self.objectspace.types['ip_type'] services = [] - if not self.objectspace.paths.has_path_prefix(): + if 1: + #FIXME if not self.objectspace.paths.has_path_prefix(): self.uniq_overrides[None] = [] - if hasattr(self.objectspace.space, 'services'): - if not hasattr(self.objectspace.space.services, 'service'): - del self.objectspace.space.services - else: - services.append((None, 'services', self.objectspace.space.services)) - elif hasattr(self.objectspace.space, 'variables'): - for path_prefix in self.objectspace.paths.get_path_prefixes(): - self.uniq_overrides[path_prefix] = [] - root_path = f'{path_prefix}.services' - if not path_prefix in self.objectspace.space.variables or \ - not hasattr(self.objectspace.space.variables[path_prefix], 'services'): - continue - if not hasattr(self.objectspace.space.variables[path_prefix].services, 'service'): - del self.objectspace.space.variables[path_prefix].services - else: - services.append((path_prefix, root_path, self.objectspace.space.variables[path_prefix].services)) - for path_prefix, root_path, service in services: - self.convert_services(path_prefix, root_path, service) + # if hasattr(self.objectspace.space, 'services'): + if self.objectspace.services: + services.append((None, 'services', self.objectspace.services)) + #elif hasattr(self.objectspace.space, 'variables'): + # for path_prefix in self.objectspace.paths.get_path_prefixes(): + # self.uniq_overrides[path_prefix] = [] + # root_path = f'{path_prefix}.services' + # if not path_prefix in self.objectspace.space.variables or \ + # not hasattr(self.objectspace.space.variables[path_prefix], 'services'): + # continue + # if not hasattr(self.objectspace.space.variables[path_prefix].services, 'service'): + # del self.objectspace.space.variables[path_prefix].services + # else: + # services.append((path_prefix, root_path, self.objectspace.space.variables[path_prefix].services)) + if services: + self.objectspace.add_family('.', + 'services', + 'services', + {'doc': 'services', + 'hidden': True, + }, + [] + ) + for path_prefix, root_path, service in services: + self.convert_services(path_prefix, root_path, service) def convert_services(self, path_prefix, root_path, services): """convert services to variables """ - services.hidden = True - services.name = 'services' - services.doc = 'services' - services.path = root_path - for service_name, service in services.service.items(): - service.name = normalize_family(service_name) - activate_obj = self._generate_element('boolean', - None, - None, - 'activate', - not service.disabled, - service, - f'{root_path}.{service.name}', - path_prefix, - ) - service.disabled = None - dico = dict(vars(service)) - if 'type' not in dico: - if service.manage: - dico['type'] = service.type - else: - dico['type'] = 'none' - for elttype, values in dico.items(): - if elttype == 'servicelist': - self.objectspace.paths.list_conditions[path_prefix].setdefault('servicelist', - {}).setdefault( - values, - []).append(activate_obj) - continue - if elttype in ERASED_ATTRIBUTES: - continue - if not service.manage and elttype not in ALLOW_ATTRIBUT_NOT_MANAGE and (elttype != 'type' or values != 'none'): - msg = _(f'unmanage service cannot have "{elttype}"') - raise DictConsistencyError(msg, 66, service.xmlfiles) - if isinstance(values, (dict, list)): - if elttype != 'ip': - eltname = elttype + 's' - else: - eltname = elttype - if hasattr(service, 'servicelist'): - if isinstance(values, dict): - for key, value in values.items(): - setattr(value, 'servicelist', service.servicelist) - family = self._gen_family(eltname, - f'{root_path}.{service.name}', - service.xmlfiles, - path_prefix, - with_informations=False, - ) - if isinstance(values, dict): - values = list(values.values()) - family.family = self.make_group_from_elts(service_name, - elttype, - values, - f'{root_path}.{service.name}.{eltname}', - root_path, - path_prefix, - ) - setattr(service, elttype, family) - else: - if not hasattr(service, 'information'): - service.information = self.objectspace.information(service.xmlfiles) - setattr(service.information, elttype, values) - service.path = f'{root_path}.{service.name}' - manage = self._generate_element('boolean', - None, - None, - 'manage', - service.manage, - service, - f'{root_path}.{service.name}', + for service_name, service in services.items(): + n_service_name = normalize_family(service_name) + path = f'{root_path}.{n_service_name}' + self.objectspace.add_family(root_path, + path, + n_service_name, + {}, + service.xmlfiles, + ) + if path in self.objectspace.ip: + obj_path = f'{path}.ip' + if obj_path not in self.objectspace.paths: + self.objectspace.add_family(path, + obj_path, + 'ip', + {}, + service.xmlfiles, + ) + for ip in self.objectspace.ip[path]: + self.convert_service_ip(ip, + obj_path, + n_service_name, path_prefix, ) - service.variable = [activate_obj, manage] - service.doc = service_name + self._generate_element('boolean', + None, + None, + 'activate', + not service.disabled, + service, + path, + path_prefix, + ) + for elttype, values in service: + if elttype in ERASED_ATTRIBUTES: + continue + if not service.manage and elttype not in ALLOW_ATTRIBUT_NOT_MANAGE and (elttype != 'type' or values is not None): + msg = _(f'unmanage service cannot have "{elttype}"') + raise DictConsistencyError(msg, 66, service.xmlfiles) + if values: + self.objectspace.informations.add(path, elttype, values) + self.objectspace.add_variable(path, + f'{path}.manage', + 'manage', + {'type': 'boolean', + 'default': True, + }, + service.xmlfiles, + ) + + def convert_service_ip(self, + ip: dict, + subpath: str, + service_name: str, + path_prefix: str, + ) -> None: + variable = self.objectspace.paths[ip.name] + if variable.type not in ['ip', 'network', 'network_cidr']: + msg = _(f'ip cannot be linked to "{variable.type}" variable "{ip.name}"') + raise DictConsistencyError(msg, 70, ip.xmlfiles) + if variable.type in ['ip', 'network_cidr'] and ip.netmask: + msg = _(f'ip with ip_type "{variable.type}" must not have netmask') + raise DictConsistencyError(msg, 59, ip.xmlfiles) + if variable.type == 'network' and not ip.netmask: + msg = _(f'ip with ip_type "{variable.type}" must have netmask') + raise DictConsistencyError(msg, 64, ip.xmlfiles) + if ip.netmask: + netmask = self.objectspace.paths[ip.netmask] + if netmask.type != 'netmask': + msg = _(f'netmask in ip must have type "netmask", not "{netmask.type}"') + raise DictConsistencyError(msg, 65, ip.xmlfiles) + name = normalize_family(ip.name) + path = f'{subpath}.{name}' + self.objectspace.add_family(subpath, + path, + name, + {'doc': ip.name}, + ip.xmlfiles, + ) + self.objectspace.add_variable(path, + f'{path}.name', + 'name', + {'type': 'symlink', + 'opt': variable, + }, + ip.xmlfiles, + ) + if ip.netmask: + self.objectspace.add_variable(path, + f'{path}.netmask', + 'netmask', + {'type': 'symlink', + 'default': variable, + }, + ip.xmlfiles, + ) + self._generate_element('boolean', + None, + None, + 'activate', + True, + #not service.disabled, + ip, + path, + path_prefix, + ) def make_group_from_elts(self, service_name, @@ -303,13 +335,13 @@ class Annotator: key, value, elt, - path, + subpath, path_prefix, ): # pylint: disable=R0913 - variable = self.objectspace.variable(elt.xmlfiles) - variable.name = normalize_family(key) - variable.mode = None - variable.type = type_ + name = normalize_family(key) + variable_obj = {'type': type_, + 'xmlfiles': elt.xmlfiles + } if type_ == 'symlink': variable.opt = self.objectspace.paths.get_variable(value, self.objectspace.rougailconfig['variable_namespace'], @@ -325,15 +357,21 @@ class Annotator: raise DictConsistencyError(msg, 58, elt.xmlfiles) else: - variable.doc = key - variable.default = value - variable.namespace = 'services' - self.objectspace.paths.add_variable('services', - path, - variable, - force_path_prefix=path_prefix - ) - return variable + variable_obj['description'] = key + variable_obj['default'] = value + path = f'{subpath}.{name}' + self.objectspace.add_variable(subpath, + path, + name, + variable_obj, + elt.xmlfiles, + ) +# self.objectspace.paths.add_variable('services', +# path, +# variable, +# force_path_prefix=path_prefix +# ) + return self.objectspace.paths[path] def _update_override(self, override, @@ -363,37 +401,6 @@ class Annotator: f'"({service_name})"') raise DictConsistencyError(msg, 34, file_.xmlfiles) - def _update_ip(self, - ip, - service_name, - path_prefix, - ) -> None: - variable = self.objectspace.paths.get_variable(ip.name, - ip.namespace, - xmlfiles=ip.xmlfiles, - force_path_prefix=path_prefix, - add_path_prefix=True, - ) - if variable.type not in ['ip', 'network', 'network_cidr']: - msg = _(f'ip cannot be linked to "{variable.type}" variable "{ip.name}"') - raise DictConsistencyError(msg, 70, ip.xmlfiles) - if variable.type in ['ip', 'network_cidr'] and hasattr(ip, 'netmask'): - msg = _(f'ip with ip_type "{variable.type}" must not have netmask') - raise DictConsistencyError(msg, 59, ip.xmlfiles) - if variable.type == 'network' and not hasattr(ip, 'netmask'): - msg = _(f'ip with ip_type "{variable.type}" must have netmask') - raise DictConsistencyError(msg, 64, ip.xmlfiles) - if hasattr(ip, 'netmask'): - netmask = self.objectspace.paths.get_variable(ip.netmask, - ip.namespace, - xmlfiles=ip.xmlfiles, - force_path_prefix=path_prefix, - add_path_prefix=True, - ) - if netmask.type != 'netmask': - msg = _(f'netmask in ip must have type "netmask", not "{netmask.type}"') - raise DictConsistencyError(msg, 65, ip.xmlfiles) - def _update_certificate(self, certificate, certificate_name, diff --git a/src/rougail/annotator/value.py b/src/rougail/annotator/value.py index ecc342d2a..3814d10f5 100644 --- a/src/rougail/annotator/value.py +++ b/src/rougail/annotator/value.py @@ -31,6 +31,7 @@ from rougail.annotator.variable import Walk from rougail.i18n import _ from rougail.error import DictConsistencyError +from rougail.annotator.fill import get_jinja_variable_to_param class Annotator(Walk): # pylint: disable=R0903 """Annotate value @@ -38,10 +39,12 @@ class Annotator(Walk): # pylint: disable=R0903 level = 70 def __init__(self, objectspace, + functions, *args, ) -> None: - if not hasattr(objectspace.space, 'variables'): + if not objectspace.paths: return + self.functions = functions self.objectspace = objectspace self.convert_value() self.add_choice_nil() @@ -50,36 +53,45 @@ class Annotator(Walk): # pylint: disable=R0903 """convert value """ for variable in self.get_variables(): + if variable.type == 'symlink': + continue self._convert_value(variable) def _convert_value(self, - variable, + variable: dict, ) -> None: # a boolean must have value, the default value is "True" - if not hasattr(variable, 'value') and variable.type == 'boolean': - new_value = self.objectspace.value(variable.xmlfiles) - new_value.name = True - new_value.type = 'boolean' - variable.value = [new_value] - # if the variable is mandatory and doesn't have any value - # then the variable's mode is set to 'basic' - # variable with default value is mandatory - if hasattr(variable, 'value') and variable.value: - has_value = True - for value in variable.value: - if value.type == 'calculation' or value.type == 'nil': - has_value = False - break - if has_value and 'mandatory' not in vars(variable): - # if has value without any calculation - variable.mandatory = True - if not hasattr(variable, 'value'): + if variable.default and variable.type == 'boolean': + variable.default = True + if not variable.default: return - if variable.value[0].type == 'calculation': - variable.default = variable.value[0] - elif variable.multi: + has_value = False + if isinstance(variable.default, dict): + if variable.default['type'] == 'jinja': + path_prefix = None + default = {'type': 'jinja', + 'name': 'jinja_to_function', + 'params': {'__internal_jinja': variable.default['name'], + '__internal_type': variable.type, + '__internal_multi': variable.multi, + }, + } + for variable in get_jinja_variable_to_param(variable.default['name'], + self.objectspace, + variable.xmlfiles, + path_prefix, + self.functions, + None, + None, + ): + default['params'][variable.path] = variable + else: + raise Exception('pfff') + elif isinstance(variable.default, list): + if not variable.multi: + raise Exception('pfff') if self.objectspace.paths.is_follower(variable): - if variable.multi != 'submulti' and len(variable.value) != 1: + if variable.multi != 'submulti' and len(variable.default) != 1: msg = _(f'the follower "{variable.name}" without multi attribute can only have one value') raise DictConsistencyError(msg, 87, variable.xmlfiles) else: @@ -89,13 +101,18 @@ class Annotator(Walk): # pylint: disable=R0903 variable.default_multi = [value.name for value in variable.value] else: variable.default_multi = variable.value[0].name + has_value = True + elif variable.multi: + #msg = _(f'the none multi variable "{variable.name}" cannot have ' + # 'more than one value') + #raise DictConsistencyError(msg, 68, variable.xmlfiles) + raise Exception('pfff') else: - if len(variable.value) > 1: - msg = _(f'the none multi variable "{variable.name}" cannot have ' - 'more than one value') - raise DictConsistencyError(msg, 68, variable.xmlfiles) - variable.default = variable.value[0].name - del variable.value + has_value = True + # variable with default value is mandatory + if has_value and variable.mandatory is None: + # if has value without any calculation + variable.mandatory = True def add_choice_nil(self) -> None: """A variable with type "Choice" that is not mandatory must has "nil" value @@ -104,11 +121,9 @@ class Annotator(Walk): # pylint: disable=R0903 if variable.type != 'choice': continue is_none = False - for choice in variable.choice: - if choice.type == 'nil': + for choice in variable.choices: + if choice is None: is_none = True + break if not variable.mandatory and not is_none: - choice = self.objectspace.choice(variable.xmlfiles) - choice.name = None - choice.type = 'nil' - variable.choice.append(choice) + variable.choices.append(None) diff --git a/src/rougail/annotator/variable.py b/src/rougail/annotator/variable.py index d686c1cb5..7bfcd67e9 100644 --- a/src/rougail/annotator/variable.py +++ b/src/rougail/annotator/variable.py @@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from rougail.i18n import _ from rougail.error import DictConsistencyError -from rougail.objspace import convert_boolean, get_variables +from rougail.objspace import convert_boolean #, get_variables CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int), @@ -75,15 +75,17 @@ class Walk: def get_variables(self): """Iter all variables from the objectspace """ - yield from get_variables(self.objectspace) + for path in self.objectspace.variables: + yield self.objectspace.paths[path] +# yield from get_variables(self.objectspace) - def get_families(self, - with_parent: bool=False, - ): + def get_families(self): """Iter all families from the objectspace """ - for family in self.objectspace.space.variables.values(): - yield from self._get_families(family, None, with_parent) + for path in self.objectspace.families: + yield self.objectspace.paths[path] +# for family in self.objectspace.space.variables.values(): +# yield from self._get_families(family, None, with_parent) def _get_families(self, family: 'self.objectspace.family', @@ -101,30 +103,30 @@ class Walk: if hasattr(family, 'variables'): for fam in family.variables.values(): yield from self._get_families(fam, family, with_parent) - - def get_constraints(self, - create: bool=False, - path_prefix: str=None, - ): - if not self.objectspace.paths.has_path_prefix(): - if hasattr(self.objectspace.space, 'constraints'): - yield None, self.objectspace.space.constraints - elif create: - self.objectspace.space.constraints = self.objectspace.constraints(None) - yield None, self.objectspace.space.constraints - else: - if path_prefix: - path_prefixes = [path_prefix] - else: - path_prefixes = self.objectspace.paths.get_path_prefixes() - for path_prefix in path_prefixes: - if hasattr(self.objectspace.space, 'variables') and \ - path_prefix in self.objectspace.space.variables and \ - hasattr(self.objectspace.space.variables[path_prefix], 'constraints'): - yield path_prefix, self.objectspace.space.variables[path_prefix].constraints - elif create: - self.objectspace.space.variables[path_prefix].constraints = self.objectspace.constraints(None) - yield path_prefix, self.objectspace.space.variables[path_prefix].constraints +# +# def get_constraints(self, +# create: bool=False, +# path_prefix: str=None, +# ): +# if not self.objectspace.paths.has_path_prefix(): +# if hasattr(self.objectspace.space, 'constraints'): +# yield None, self.objectspace.space.constraints +# elif create: +# self.objectspace.space.constraints = self.objectspace.constraints(None) +# yield None, self.objectspace.space.constraints +# else: +# if path_prefix: +# path_prefixes = [path_prefix] +# else: +# path_prefixes = self.objectspace.paths.get_path_prefixes() +# for path_prefix in path_prefixes: +# if hasattr(self.objectspace.space, 'variables') and \ +# path_prefix in self.objectspace.space.variables and \ +# hasattr(self.objectspace.space.variables[path_prefix], 'constraints'): +# yield path_prefix, self.objectspace.space.variables[path_prefix].constraints +# elif create: +# self.objectspace.space.variables[path_prefix].constraints = self.objectspace.constraints(None) +# yield path_prefix, self.objectspace.space.variables[path_prefix].constraints class Annotator(Walk): # pylint: disable=R0903 @@ -135,7 +137,7 @@ class Annotator(Walk): # pylint: disable=R0903 objectspace, *args, ): - if not hasattr(objectspace.space, 'variables'): + if not objectspace.paths: return self.objectspace = objectspace self.forbidden_name = ['services', self.objectspace.rougailconfig['variable_namespace']] @@ -152,14 +154,10 @@ class Annotator(Walk): # pylint: disable=R0903 self._convert_variable(variable) def _convert_variable(self, - variable, + variable: dict, ) -> None: - if variable.namespace == self.objectspace.rougailconfig['variable_namespace'] and \ - variable.name in self.forbidden_name: - msg = _(f'the name of the variable "{variable.name}" cannot be the same as the name' - ' of a namespace') - raise DictConsistencyError(msg, 54, variable.xmlfiles) - if variable.type != 'symlink' and not hasattr(variable, 'description'): + # variable without description: description is the name + if variable.type != 'symlink' and not variable.description: variable.description = variable.name if hasattr(variable, 'value'): for idx, value in enumerate(variable.value): @@ -178,54 +176,56 @@ class Annotator(Walk): # pylint: disable=R0903 value.name = None if not variable.value: del variable.value - if hasattr(variable, 'choice'): + if hasattr(variable, 'choices') and variable.choices is not None: if variable.type != 'choice': msg = _(f'choice for the variable "{variable.name}" not allowed with "{variable.type}" type') raise DictConsistencyError(msg, 3, variable.xmlfiles) values = [] choice_type = None - for choice in variable.choice: - if choice_type == 'variable': - msg = _(f'only one "variable" choice is allowed ' - f'the variable "{variable.name}"') - raise DictConsistencyError(msg, 5, choice.xmlfiles) - if choice.type == 'nil': - choice.name = None - elif choice.type == 'space': - choice.name = ' ' - elif choice.type == 'variable': - choice.name = self.objectspace.paths.get_variable(choice.name, - variable.namespace, - force_path_prefix=variable.path_prefix, - ) - if not choice.name.multi: - msg = _(f'only multi "variable" is allowed for a choice ' - f'of variable "{variable.name}"') - raise DictConsistencyError(msg, 6, choice.xmlfiles) - else: - if not hasattr(choice, 'name'): - msg = _(f'choice for variable "{variable.name}" must have a value') - raise DictConsistencyError(msg, 14, choice.xmlfiles) - choice.name = CONVERT_OPTION.get(choice.type, {}).get('func', str)(choice.name) - if choice_type is None: - choice_type = choice.type - values.append(choice.name) - if choice_type not in ['function', 'variable'] and hasattr(variable, 'value'): - for value in variable.value: - if value.name not in values: - msg = _(f'value "{value.name}" of variable "{variable.name}" is not in list ' - f'of all expected values ({values})') - raise DictConsistencyError(msg, 15, value.xmlfiles) - ref_choice = variable.choice[0] - self.objectspace.paths.set_valid_enums(variable.path, - values, - variable.path_prefix, - ) + for choice in variable.choices: + #if choice_type == 'variable': + # msg = _(f'only one "variable" choice is allowed ' + # f'the variable "{variable.name}"') + # raise DictConsistencyError(msg, 5, choice.xmlfiles) + #if choice.type == 'nil': + # choice.name = None + #elif choice.type == 'space': + # choice.name = ' ' + if isinstance(choice, dict): + if choice['type'] == 'variable': + obj = self.objectspace.paths[choice['value']] + #FIXME? + if not obj.multi: + msg = _(f'only multi "variable" is allowed for a choice ' + f'of variable "{variable.name}"') + raise DictConsistencyError(msg, 6, choice['xmlfiles']) + #values.append(obj) + elif choice['type'] != 'jinja': + raise Exception('hu?') + # else: + # if not hasattr(choice, 'name'): + # msg = _(f'choice for variable "{variable.name}" must have a value') + # raise DictConsistencyError(msg, 14, choice.xmlfiles) + # choice.name = CONVERT_OPTION.get(choice.type, {}).get('func', str)(choice.name) + #if choice_type is None: + # choice_type = choice.type +# else: +# values.append(choice) + # FIXME if variable.values: + # FIXME for value in variable.values: + # FIXME if value not in values: + # FIXME msg = _(f'value "{value.name}" of variable "{variable.name}" is not in list ' + # FIXME f'of all expected values ({values})') + # FIXME raise DictConsistencyError(msg, 15, value.xmlfiles) + #ref_choice = variable.choices[0] + self.objectspace.choices.append(variable.path, + values, + ) elif variable.type == 'choice': msg = _(f'choice is mandatory for the variable "{variable.name}" with choice type') raise DictConsistencyError(msg, 4, variable.xmlfiles) - variable.doc = variable.description - del variable.description +# variable.doc = variable.description +# del variable.description def convert_test(self): """Convert variable tests value @@ -241,17 +241,13 @@ class Annotator(Walk): # pylint: disable=R0903 else: value = CONVERT_OPTION.get(variable.type, {}).get('func', str)(value) new_values.append(value) - if not hasattr(variable, 'information'): - variable.information = self.objectspace.information(variable.xmlfiles) - variable.information.test = tuple(new_values) + self.objectspace.informations.add(variable.path, 'test', tuple(new_values)) def convert_help(self): """Convert variable help """ for variable in self.get_variables(): - if not hasattr(variable, 'help'): + if not hasattr(variable, 'help') or not variable.help: continue - if not hasattr(variable, 'information'): - variable.information = self.objectspace.information(variable.xmlfiles) - variable.information.help = variable.help + self.objectspace.informations.add(variable.path, 'help', variable.help) del variable.help diff --git a/src/rougail/config.py b/src/rougail/config.py index caa763501..cdb07707f 100644 --- a/src/rougail/config.py +++ b/src/rougail/config.py @@ -36,6 +36,7 @@ DTDDIR = join(dirname(abspath(__file__)), 'data') RougailConfig = {'dictionaries_dir': [join(ROUGAILROOT, 'dictionaries')], + 'services_dir': [join(ROUGAILROOT, 'services')], 'extra_dictionaries': {}, 'patches_dir': join(ROUGAILROOT, 'patches'), 'templates_dir': join(ROUGAILROOT, 'templates'), diff --git a/src/rougail/convert.py b/src/rougail/convert.py index d98d05cb7..bfb216687 100644 --- a/src/rougail/convert.py +++ b/src/rougail/convert.py @@ -54,7 +54,7 @@ from .reflector import Reflector from .tiramisureflector import TiramisuReflector from .annotator import SpaceAnnotator from .error import DictConsistencyError -from .providersupplier import provider_supplier +#from .providersupplier import provider_supplier from .utils import normalize_family @@ -97,10 +97,10 @@ class RougailConvert: extra_dir, path_prefix, ) - if hasattr(self.rougailobjspace.space, 'variables'): - provider_supplier(self.rougailobjspace, - path_prefix, - ) +# if hasattr(self.rougailobjspace.space, 'variables'): +# provider_supplier(self.rougailobjspace, +# path_prefix, +# ) self.dictionaries = True def _load_dictionaries(self, diff --git a/src/rougail/new_test.py b/src/rougail/new_test.py new file mode 100644 index 000000000..4cd4c480c --- /dev/null +++ b/src/rougail/new_test.py @@ -0,0 +1,488 @@ +from typing import Optional, Union, get_type_hints, Any, Literal, List +from pydantic import BaseModel + +from yaml import safe_load +from os import listdir +from os.path import join, isdir + +from .annotator import SpaceAnnotator +from .tiramisureflector import TiramisuReflector +from .utils import normalize_family + + +class Family(BaseModel): + name: str + description: Optional[str] + type: Literal['family', 'leadership', 'dynamic']='family' + help: Optional[str] + mode: Optional[str] + hidden: Union[bool, str]=False + disabled: Union[bool, str]=False + xmlfiles: List[str]=[] + path: str + + +class Variable(BaseModel): + name: str + type: Literal['number', 'float', 'string', 'password', 'secret', 'mail', 'boolean', 'filename', 'date', 'unix_user', 'ip', 'local_ip', 'netmask', 'network', 'broadcast', 'netbios', 'domainname', 'hostname', 'web_address', 'port', 'mac', 'cidr', 'network_cidr', 'choice', 'unix_permissions']='string' + description: Optional[str] + default: Any + choices: Any + validators: Any + multi: bool=False + unique: Optional[bool]=None + help: Optional[str] + hidden: Union[bool, str]=False + disabled: Union[bool, str]=False + mandatory: Union[None, bool, str] + auto_freeze: bool=False + auto_save: bool=False + mode: Optional[str] + provider: Optional[str] + supplier: Optional[str] + test: Any + xmlfiles: List[str]=[] + path: str + + +class SymLink(BaseModel): + name: str + type: str='symlink' + opt: Variable + xmlfiles: List[str]=[] + path: str + + +class Service(BaseModel): + name: str + manage: bool=True + type: Literal['service', 'mount', 'swap', 'timer', 'target']='service' + disabled: Union[bool, str]=False + engine: Optional[str] + target: Optional[str] + undisable: bool=False + xmlfiles: List[str]=[] + + +class IP(BaseModel): + name: str + netmask: Optional[str] + disabled: Union[bool, str]=False + xmlfiles: List[str]=[] + + +class Appendable: + def __init__(self) -> None: + self._data = {} + + def append(self, + path: str, + data: str, + ) -> None: + if path not in self._data: + self._data[path] = [] + self._data[path].append(data) + + def __getitem__(self, + path: str, + ) -> list: + return self._data.get(path, []) + + def __contains__(self, + path: str, + ) -> bool: + return path in self._data + + +class Paths: + def __init__(self) -> None: + self._data = {} + + def add(self, + path: str, + data: str, + ) -> None: + if path in self._data: + raise Exception('pfff') + self._data[path] = data + + def __getitem__(self, + path: str, + ) -> dict: + if not path in self._data: + raise Exception(f'cannot find variable or family {path}') + return self._data[path] + + def is_family(self, path: str): + if not path in self._data: + raise Exception(f'cannot find family {path}') + return isinstance(self._data[path], Family) + + def __contains__(self, + path: str, + ) -> bool: + return path in self._data + + def get(self): + return self._data.values() + + +class Informations: + def __init__(self) -> None: + self._data = {} + + def add(self, + path: str, + key: str, + data: Any, + ) -> None: + if data is None: + raise Exception('connard') + if path not in self._data: + self._data[path] = {} + if key in self._data[path]: + raise Exception(f'already key {key} in {path}') + self._data[path][key] = data + + def get(self, + path: str, + ) -> List[str]: + return self._data.get(path, []) + + +class ParserVariable: + def __init__(self): + self.paths = Paths() + self.families = [] + self.variables = [] + self.parents = {'.': []} + self.index = 0 + self.reflector_names = {} + self.family = Family + self.variable = Variable + #FIXME + self.exclude_imports = [] + self.informations = Informations() + self.properties = Appendable() + self.choices = Appendable() + super().__init__() + + def parse_variable_file(self, + filename: str, + namespace: str, +# description: str, + ) -> None: + with open(filename) as o: + objects = safe_load(o) + self.validate_file_version(objects) + self.parents[namespace] = [] +# self.parse_family(filename, namespace, '.', namespace, {'description': description}) + self.parse_family(filename, namespace, '.', namespace, {}) + for name, obj in objects.items(): + self.family_or_variable(filename, + name, + namespace, + obj, + ) + + def family_or_variable(self, + filename: str, + name: str, + subpath: str, + obj: dict, + ) -> None: + if subpath: + path = f'{subpath}.{name}' + else: + path = name + if 'type' in obj: + if obj['type'] in ['family', 'dynamic', 'leadership']: + typ = 'family' + else: + typ = 'variable' + else: + if path in self.paths: + if self.paths.is_family(path): + typ = 'family' + else: + typ = 'variable' + else: + extra_keys = set(obj) - FAMILY_ATTRS + typ = 'family' + for key in extra_keys: + value = obj[key] + if not isinstance(value, dict): + typ = 'variable' + break + if typ == 'family': + parser = self.parse_family + else: + parser = self.parse_variable + parser(filename, name, subpath, path, obj) + + def parse_family(self, + filename: str, + name: str, + subpath: str, + path: str, + family: dict, + ) -> None: + family_obj = {} + subfamily_obj = {} + for key, value in family.items(): + if key.startswith('_'): + key = key[1:] + if key in FAMILY_ATTRS and not isinstance(value, dict): + family_obj[key] = value + else: + subfamily_obj[key] = value + if path in self.paths: + if family_obj: + if not family.pop('redefine', False): + raise Exception('pfff') + self.paths.add(path, self.paths[path].copy(update=family)) + self.paths[path].xmlfiles.append(filename) + else: + extra_attrs = set(family_obj) - FAMILY_ATTRS + if extra_attrs: + raise Exception(f'extra attrs ... {extra_attrs}') + self.add_family(subpath, + path, + name, + family_obj, + filename, + ) + for key, value in subfamily_obj.items(): + if not isinstance(value, dict): + raise Exception(f'pfff {key}') + self.family_or_variable(filename, + key, + path, + value, + ) + + def add_family(self, + subpath: str, + path: str, + name: str, + family: dict, + filename: str, + ) -> None: + family['path'] = path + if not isinstance(filename, list): + filename = [filename] + family['xmlfiles'] = filename + self.paths.add(path, self.family(name=name, **family)) + self.set_name(self.paths[path], 'optiondescription_') + self.parents[subpath].append(path) + self.parents[path] = [] + self.families.append(path) + + def parse_variable(self, + filename: str, + name: str, + subpath: str, + path: str, + variable: dict, + ) -> None: + extra_attrs = set(variable) - VARIABLE_ATTRS + if extra_attrs: + raise Exception(f'extra attrs ... {extra_attrs}') + if path in self.paths: + if 'exists' in variable and not variable['exists']: + return + if not variable.pop('redefine', False): + raise Exception('pfff') + self.paths.add(path, self.paths[path].copy(update=variable)) + self.paths[path].xmlfiles.append(filename) + else: + if 'exists' in variable and variable.pop('exists'): + # this variable must exist + # but it's not the case + # so do nothing + return + if 'redefine' in variable and variable['redefine']: + raise Exception('cannot redefine!') + self.add_variable(subpath, + path, + name, + variable, + filename, + ) + + def add_variable(self, + subpath: str, + path: str, + name: str, + variable: dict, + filename: str, + ) -> None: + variable['path'] = path + if not isinstance(filename, list): + filename = [filename] + variable['xmlfiles'] = filename + if variable.get('type') == 'symlink': + variable_obj = SymLink(name=name, **variable) + else: + variable_obj = self.variable(name=name, **variable) + self.paths.add(path, variable_obj) + self.variables.append(path) + self.parents[subpath].append(path) + self.set_name(variable_obj, 'option_') + + +class ParserService: + def __init__(self): + self.service = Service + self.services = {} + self.ip = {} + + def parse_service_file(self, + filename: str, + ) -> None: + with open(filename) as o: + objects = safe_load(o) + self.validate_file_version(objects) + for name, obj in objects.items(): + self.parse_service(filename, + name, + obj, + ) + + def parse_service(self, + filename: str, + name: str, + service: dict, + ) -> None: + service_obj = {} + subservice_obj = {} + for key, value in service.items(): + if key.startswith('_'): + key = key[1:] + if key in SERVICE_ATTRS and not isinstance(value, dict): + service_obj[key] = value + else: + subservice_obj[key] = value + if name in self.services: + if service_obj: + if not service.pop('redefine', False): + raise Exception('pfff') + self.services[name] = self.services[name].copy(update=service) + else: + if '.' not in name: + raise Exception('pffff') + extra_attrs = set(service_obj) - SERVICE_ATTRS + if extra_attrs: + raise Exception(f'extra attrs ... {extra_attrs}') + service_obj['type'] = name.rsplit('.')[1] + self.services[name] = self.service(name=name, **service_obj) + self.services[name].xmlfiles.append(filename) + for key, value in subservice_obj.items(): + if not isinstance(value, dict): + raise Exception(f'pfff {key}') + for subname, subvalue in value.items(): + getattr(self, f'parse_service_{key}')(subname, subvalue, f'services.{normalize_family(name)}', filename) + + def parse_service_ip(self, + name: str, + ip: dict, + path: str, + filename: str, + ) -> None: + extra_attrs = set(ip) - IP_ATTRS + if extra_attrs: + raise Exception(f'extra attrs ... {extra_attrs}') + self.ip.setdefault(path, []).append(IP(name=name, **ip)) + self.ip[path][-1].xmlfiles.append(filename) + + +class Parser(ParserVariable, ParserService): + supported_version = ['1.0'] + + def __init__(self, + rougailconfig: 'RougailConfig' + ) -> None: + # FIXME useful? + self.annotator = False + self.rougailconfig = rougailconfig + super().__init__() + self.parse_directories() + self.annotate() + self.reflect() + + def parse_directories(self) -> None: + for filename in self.get_sorted_filename(self.rougailconfig['dictionaries_dir']): + namespace = self.rougailconfig['variable_namespace'] + #self.parents['.'].append(namespace) + self.parse_variable_file(filename, + namespace, +# self.rougailconfig['variable_namespace_description'], + ) + for namespace, extra_dirs in self.rougailconfig['extra_dictionaries'].items(): + #self.parents['.'].append(namespace) + for filename in self.get_sorted_filename(extra_dirs): + self.parse_variable_file(filename, + namespace, +# namespace, + ) + for filename in self.get_sorted_filename(self.rougailconfig['services_dir']): + self.parse_service_file(filename) + + def get_sorted_filename(self, + directories: Union[str, List[str]], + ) -> List[str]: + filenames = {} + if not isinstance(directories, list): + directories = [directories] + for directory in directories: + if not isdir(directory): + continue + for filename in listdir(directory): + if not filename.endswith('.yml'): + continue + full_filename = join(directory, filename) + if filename in filenames: + raise DictConsistencyError(_(f'duplicate dictionary file name {filename}'), 78, [filenames[filename][1], full_filename]) + filenames[filename] = full_filename + for filename in sorted(filenames): + yield filenames[filename] + + def validate_file_version(self, + obj: dict, + ) -> None: + if 'version' not in obj: + raise Exception('version ...') + version = obj.pop('version') + if version not in self.supported_version: + raise Exception(f'pffff version ... {version} not in {self.supported_version}') + + def set_name(self, + obj, + option_prefix, + ): + self.index += 1 + self.reflector_names[obj.path] = f'{option_prefix}{self.index}{self.rougailconfig["suffix"]}' + + def annotate(self): + if self.annotator: + raise DictConsistencyError(_('Cannot execute annotate multiple time'), 85, None) + SpaceAnnotator(self) + self.annotator = True + + def reflect(self): + functions_file = self.rougailconfig['functions_file'] + if not isinstance(functions_file, list): + functions_file = [functions_file] + functions_file = [func for func in functions_file if func not in self.exclude_imports] + self.reflector = TiramisuReflector(self, + functions_file, + ) + + def get(self): + return self.reflector.get_text() + + +FAMILY_ATTRS = frozenset(list(get_type_hints(Family)) + ['redefine']) +VARIABLE_ATTRS = frozenset(list(get_type_hints(Variable)) + ['redefine', 'exists']) +SERVICE_ATTRS = frozenset(list(get_type_hints(Service)) + ['redefine', 'type']) +IP_ATTRS = frozenset(list(get_type_hints(IP))) diff --git a/src/rougail/objspace.py b/src/rougail/objspace.py index 7eb0db904..799ec7a4f 100644 --- a/src/rougail/objspace.py +++ b/src/rougail/objspace.py @@ -90,6 +90,7 @@ class ObjSpace: # pylint: disable=R0903 def convert_boolean(value: str) -> bool: """Boolean coercion. The Rougail XML may contain srings like `True` or `False` """ + print('FIXME') if isinstance(value, bool): return value if value == 'True': @@ -587,24 +588,24 @@ class RougailObjSpace: getattr(space, child.tag).append(variableobj) else: setattr(space, child.tag, variableobj) - - -def get_variables(objectspace): - """Iter all variables from the objectspace - """ - if not hasattr(objectspace.space, 'variables'): - return - for family in objectspace.space.variables.values(): - yield from _get_variables(family, objectspace.family) - - -def _get_variables(family, family_type): - if hasattr(family, 'variable'): - for variable in family.variable.values(): - if isinstance(variable, family_type): - yield from _get_variables(variable, family_type) - else: - yield variable - if hasattr(family, 'variables'): - for family in family.variables.values(): - yield from _get_variables(family, family_type) +# +# +#def get_variables(objectspace): +# """Iter all variables from the objectspace +# """ +# if not hasattr(objectspace.space, 'variables'): +# return +# for family in objectspace.space.variables.values(): +# yield from _get_variables(family, objectspace.family) +# +# +#def _get_variables(family, family_type): +# if hasattr(family, 'variable'): +# for variable in family.variable.values(): +# if isinstance(variable, family_type): +# yield from _get_variables(variable, family_type) +# else: +# yield variable +# if hasattr(family, 'variables'): +# for family in family.variables.values(): +# yield from _get_variables(family, family_type) diff --git a/src/rougail/providersupplier.py b/src/rougail/providersupplier.py index 59365929d..35b9e12b4 100644 --- a/src/rougail/providersupplier.py +++ b/src/rougail/providersupplier.py @@ -16,26 +16,26 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -from rougail.objspace import get_variables -from rougail.utils import normalize_family - - -def provider_supplier(objectspace, - path_prefix, - ): - n_path_prefix = normalize_family(path_prefix) - for variable in get_variables(objectspace): - if variable.path_prefix != n_path_prefix: - continue - if hasattr(variable, 'provider'): - family_name, variable.name = variable.path.rsplit('.', 1) - objectspace.paths.set_provider(variable, - variable.name, - family_name, - ) - if hasattr(variable, 'supplier'): - family_name, variable.name = variable.path.rsplit('.', 1) - objectspace.paths.set_supplier(variable, - variable.name, - family_name, - ) +#from rougail.objspace import get_variables +#from rougail.utils import normalize_family +# +# +#def provider_supplier(objectspace, +# path_prefix, +# ): +# n_path_prefix = normalize_family(path_prefix) +# for variable in get_variables(objectspace): +# if variable.path_prefix != n_path_prefix: +# continue +# if hasattr(variable, 'provider'): +# family_name, variable.name = variable.path.rsplit('.', 1) +# objectspace.paths.set_provider(variable, +# variable.name, +# family_name, +# ) +# if hasattr(variable, 'supplier'): +# family_name, variable.name = variable.path.rsplit('.', 1) +# objectspace.paths.set_supplier(variable, +# variable.name, +# family_name, +# ) diff --git a/src/rougail/tiramisureflector.py b/src/rougail/tiramisureflector.py index 68cc2716f..d94c52260 100644 --- a/src/rougail/tiramisureflector.py +++ b/src/rougail/tiramisureflector.py @@ -56,17 +56,16 @@ class TiramisuReflector: def __init__(self, objectspace, funcs_paths, - internal_functions, - cfg, ): - self.cfg = cfg + self.rougailconfig = objectspace.rougailconfig self.jinja_added = False + self.reflector_objects = {} self.text = {'header': [], 'option': [], 'optiondescription': [], } if funcs_paths: - if self.cfg['export_with_import']: + if self.rougailconfig['export_with_import']: self.text['header'].extend(["from importlib.machinery import SourceFileLoader as _SourceFileLoader", "from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec", "class func:", @@ -87,9 +86,9 @@ class TiramisuReflector: if not isfile(funcs_path): continue self.text['header'].append(f"_load_functions('{funcs_path}')") - if self.cfg['export_with_import']: - if internal_functions: - for func in internal_functions: + if self.rougailconfig['export_with_import']: + if self.rougailconfig['internal_functions']: + for func in self.rougailconfig['internal_functions']: self.text['header'].append(f"setattr(func, '{func}', {func})") self.text['header'].extend(["try:", " from tiramisu4 import *", @@ -98,12 +97,12 @@ class TiramisuReflector: " from tiramisu import *", " from tiramisu.setting import ALLOWED_LEADER_PROPERTIES", ]) - for mode in objectspace.rougailconfig["modes_level"]: + for mode in self.rougailconfig["modes_level"]: self.text['header'].append(f'ALLOWED_LEADER_PROPERTIES.add("{mode}")') self.objectspace = objectspace self.make_tiramisu_objects() - if self.cfg['export_with_import'] and (self.cfg['force_convert_dyn_option_description'] or self.objectspace.has_dyn_option is True): - self.text['header'].append("from rougail.tiramisu import ConvertDynOptionDescription") +#FIXME if self.rougailconfig['export_with_import'] and (self.rougailconfig['force_convert_dyn_option_description'] or self.objectspace.has_dyn_option is True): +# self.text['header'].append("from rougail.tiramisu import ConvertDynOptionDescription") def add_jinja_to_function(self, variable_name: str, @@ -146,20 +145,30 @@ class TiramisuReflector: """make tiramisu objects """ baseelt = BaseElt() - baseelt.reflector_name = f'option_0{self.objectspace.rougailconfig["suffix"]}' - self.set_name(baseelt) + self.objectspace.reflector_names[baseelt.path] = f'option_0{self.rougailconfig["suffix"]}' basefamily = Family(baseelt, self, ) - if not self.objectspace.paths.has_path_prefix(): - for elt in self.reorder_family(self.objectspace.space): - self.populate_family(basefamily, - elt, - ) - if not hasattr(basefamily.elt, 'information'): - basefamily.elt.information = self.objectspace.information(None) - basefamily.elt.information = self.objectspace.paths.get_providers_path() - basefamily.elt.information.update(self.objectspace.paths.get_suppliers_path()) + #FIXMEif not self.objectspace.paths.has_path_prefix(): + if 1: +# for elt in self.reorder_family(self.objectspace.space): + for elt in self.objectspace.paths.get(): + if elt.path in self.objectspace.families: + Family(elt, + self, + ) + else: + Variable(elt, + self, + ) + +# self.populate_family(basefamily, +# elt, +# ) +#FIXME if not hasattr(basefamily.elt, 'information'): +# basefamily.elt.information = self.objectspace.information(None) +# basefamily.elt.information = self.objectspace.paths.get_providers_path() +# basefamily.elt.information.update(self.objectspace.paths.get_suppliers_path()) else: path_prefixes = self.objectspace.paths.get_path_prefixes() for path_prefix in path_prefixes: @@ -179,66 +188,67 @@ class TiramisuReflector: setattr(baseprefix.elt.information, key, value) for key, value in self.objectspace.paths.get_suppliers_path(path_prefix).items(): setattr(baseprefix.elt.information, key, value) - baseelt.name = normalize_family(self.cfg['base_option_name']) - baseelt.doc = self.cfg['base_option_name'] - baseelt.reflector_object.get([], baseelt.doc, 'base') # pylint: disable=E1101 - - def reorder_family(self, space): - """variable_namespace family has to be loaded before any other family - because `extra` family could use `variable_namespace` variables. - """ - if hasattr(space, 'variables'): - variable_namespace = self.objectspace.rougailconfig['variable_namespace'] - if variable_namespace in space.variables: - yield space.variables[variable_namespace] - for elt, value in space.variables.items(): - if elt != self.objectspace.rougailconfig['variable_namespace']: - yield value - if hasattr(space, 'services'): - yield space.services - - def populate_family(self, - parent_family, - elt, - ): - """Populate family - """ - self.set_name(elt) - family = Family(elt, - self, - ) - parent_family.add(family) - for children in vars(elt).values(): - if isinstance(children, self.objectspace.family): - self.populate_family(family, - children, - ) - continue - if isinstance(children, dict): - children = list(children.values()) - if isinstance(children, list): - for child in children: - if isinstance(child, self.objectspace.property_) or \ - not isinstance(child, RootRougailObject): - continue - if isinstance(child, self.objectspace.variable): - self.set_name(child) - family.add(Variable(child, - self, - )) - else: - self.populate_family(family, - child, - ) + baseelt.name = normalize_family(self.rougailconfig['base_option_name']) + baseelt.description = self.rougailconfig['base_option_name'] + self.reflector_objects[baseelt.path].get([], baseelt.description, 'base') # pylint: disable=E1101 +# +# def reorder_family(self, space): +# """family has to be loaded before any other family +# because `extra` family could use `variable_namespace` variables. +# """ +# if hasattr(space, 'variables'): +# variable_namespace = self.rougailconfig['variable_namespace'] +# if variable_namespace in space.variables: +# yield space.variables[variable_namespace] +# for elt, value in space.variables.items(): +# if elt != self.rougailconfig['variable_namespace']: +# yield value +# if hasattr(space, 'services'): +# yield space.services +# +# def populate_family(self, +# parent_family, +# elt, +# ): +# """Populate family +# """ +# self.set_name(elt) +# family = Family(elt, +# self, +# ) +# parent_family.add(family) +# for children in vars(elt).values(): +# print('pouet', children) +# if isinstance(children, self.objectspace.family): +# self.populate_family(family, +# children, +# ) +# continue +# if isinstance(children, dict): +# children = list(children.values()) +# if isinstance(children, list): +# for child in children: +# if isinstance(child, self.objectspace.property_) or \ +# not isinstance(child, RootRougailObject): +# continue +# if isinstance(child, self.objectspace.variable): +# self.set_name(child) +# family.add(Variable(child, +# self, +# )) +# else: +# self.populate_family(family, +# child, +# ) def set_name(self, elt, ): """Set name """ - if not hasattr(elt, 'reflector_name'): - self.objectspace.paths.set_name(elt, 'optiondescription_') - return elt.reflector_name + if elt.path not in self.objectspace.reflector_names: + self.objectspace.set_name(elt, 'optiondescription_') + return self.objectspace.reflector_names[elt.path] def get_text(self): """Get text @@ -257,10 +267,11 @@ class Common: elt, tiramisu, ): + self.objectspace = tiramisu.objectspace self.elt = elt self.option_name = None self.tiramisu = tiramisu - self.elt.reflector_object = self + tiramisu.reflector_objects[elt.path] = self self.object_type = None def get(self, calls, parent_name, typ): @@ -273,7 +284,7 @@ class Common: self_calls.append(self.elt.path) self.calls = self_calls if self.option_name is None: - self.option_name = self.elt.reflector_name + self.option_name = self.objectspace.reflector_names[self.elt.path] self.populate_attrib() self.populate_informations() return self.option_name @@ -282,11 +293,11 @@ class Common: """Populate attributes """ keys = {'name': self.convert_str(self.elt.name)} - if hasattr(self.elt, 'doc'): - keys['doc'] = self.convert_str(self.elt.doc) + if hasattr(self.elt, 'description') and self.elt.description: + keys['doc'] = self.convert_str(self.elt.description) self._populate_attrib(keys) - if hasattr(self.elt, 'properties'): - keys['properties'] = self.properties_to_string(self.elt.properties) + if self.elt.path in self.objectspace.properties: + keys['properties'] = self.properties_to_string(self.objectspace.properties[self.elt.path]) attrib = ', '.join([f'{key}={value}' for key, value in keys.items()]) if self.__class__.__name__ == 'Family': #pouet @@ -315,7 +326,7 @@ class Common: properties = [self.convert_str(property_) for property_ in values if isinstance(property_, str)] calc_properties = [self.calc_properties(property_) for property_ in values \ - if isinstance(property_, self.tiramisu.objectspace.property_)] + if isinstance(property_, dict)] return 'frozenset({' + ', '.join(sorted(properties) + calc_properties) + '})' def calc_properties(self, @@ -323,7 +334,7 @@ class Common: ) -> str: """Populate properties """ - option_name = child.source.reflector_object.get(self.calls, self.elt.path, 'property') + option_name = self.tiramisu.reflector_objects[child.source.path].get(self.calls, self.elt.path, 'property') kwargs = (f"'condition': ParamOption({option_name}, notraisepropertyerror=True), " f"'expected': {self.populate_param(child.expected)}") if child.inverse: @@ -334,15 +345,10 @@ class Common: def populate_informations(self): """Populate Tiramisu's informations """ - if not hasattr(self.elt, 'information'): + informations = self.objectspace.informations.get(self.elt.path) + if not informations: return - if isinstance(self.elt.information, dict): - informations = self.elt.information - else: - informations = vars(self.elt.information) for key, value in informations.items(): - if key == 'xmlfiles': - continue if isinstance(value, str): value = self.convert_str(value) self.tiramisu.text['option'].append(f"{self.option_name}.impl_set_information('{key}', {value})") @@ -364,7 +370,7 @@ class Common: if hasattr(param, 'variable'): if param.variable.path == self.elt.path: return f'ParamSelfInformation("{param.text}", {default})' - return f'ParamInformation("{param.text}", {default}, option={param.variable.reflector_object.get(self.calls, self.elt.path, "param")})' + return f'ParamInformation("{param.text}", {default}, option={self.tiramisu.reflector_objects[param.variable.path].get(self.calls, self.elt.path, "param")})' return f'ParamInformation("{param.text}", {default})' if param.type == 'suffix': return 'ParamSuffix()' @@ -382,13 +388,13 @@ class Common: """build variable parameters """ if param.type == 'variable': - option_name = param.text.reflector_object.get(self.calls, self.elt.path, 'param') + option_name = self.tiramisu.reflector_objects[param.text.path].get(self.calls, self.elt.path, 'param') else: option_name = param.text params = [f'{option_name}'] if hasattr(param, 'suffix'): param_type = 'ParamDynOption' - family = param.family.reflector_object.get(self.calls, self.elt.path, 'suffix') + family = self.tiramisu.reflector_objects[param.family.path].get(self.calls, self.elt.path, 'suffix') params.extend([f"'{param.suffix}'", f'{family}']) if param.optional: params.append('optional=True') @@ -412,12 +418,12 @@ class Variable(Common): def _populate_attrib(self, keys: dict, ): - if hasattr(self.elt, 'opt'): - keys['opt'] = self.elt.opt.reflector_object.get(self.calls, self.elt.path, 'opt') + if self.elt.type == 'symlink': + keys['opt'] = self.tiramisu.reflector_objects[self.elt.opt.path].get(self.calls, self.elt.path, 'opt') if hasattr(self.elt, 'choice'): values = self.elt.choice if values[0].type == 'variable': - value = values[0].name.reflector_object.get(self.calls, self.elt.path, 'choice') + value = self.tiramisu.reflector_objects[values[0].name.path].get(self.calls, self.elt.path, 'choice') keys['values'] = f"Calculation(func.calc_value, Params((ParamOption({value}))))" elif values[0].type == 'function': keys['values'] = self.calculation_value(values[0], []) @@ -430,12 +436,12 @@ class Variable(Common): value = getattr(self.elt, key) if isinstance(value, str): value = self.convert_str(value) - elif isinstance(value, self.tiramisu.objectspace.value): - value = self.calculation_value(value, [], calc_multi=value.calc_multi) + elif isinstance(value, dict): + value = self.calculation_value(value, [], calc_multi=key == 'calc_multi') keys[key] = value - if hasattr(self.elt, 'validators'): - keys['validators'] = '[' + ', '.join([self.calculation_value(val, - ['ParamSelfOption(whole=False)']) for val in self.elt.validators]) + ']' +#FIXME if self.elt.validators: +# keys['validators'] = '[' + ', '.join([self.calculation_value(val, +# ['ParamSelfOption(whole=False)']) for val in self.elt.validators]) + ']' for key in ['min_number', 'max_number']: if hasattr(self.elt, key): keys[key] = getattr(self.elt, key) @@ -453,15 +459,15 @@ class Variable(Common): """ kwargs = [] # has parameters - function = child.name + function = child['name'] new_args = [] - if hasattr(child, 'param'): - for param in child.param: + if 'param' in child: + for param in child['param']: value = self.populate_param(param) - if not hasattr(param, 'name'): + if not name in param: new_args.append(str(value)) else: - kwargs.append(f"'{param.name}': " + value) + kwargs.append(f"'{param['name']}': " + value) if function == 'valid_network_netmask': new_args.extend(args) else: @@ -505,6 +511,9 @@ class Family(Common): keys: list, ) -> None: if hasattr(self.elt, 'suffixes'): - dyn = self.elt.suffixes.reflector_object.get(self.calls, self.elt.path, 'suffixes') + dyn = self.tiramisu.reflector_objects[self.elt.suffixes.path].get(self.calls, self.elt.path, 'suffixes') keys['suffixes'] = f"Calculation(func.calc_value, Params((ParamOption({dyn}, notraisepropertyerror=True))))" - keys['children'] = '[' + ', '.join([child.get(self.calls, self.elt.path, 'child') for child in self.children]) + ']' + children = [] + for path in self.objectspace.parents[self.elt.path]: + children.append(self.objectspace.paths[path]) + keys['children'] = '[' + ', '.join([self.tiramisu.reflector_objects[child.path].get(self.calls, self.elt.path, 'child') for child in children]) + ']' diff --git a/src/rougail/update.py b/src/rougail/update.py index e519d4fb9..910ec19b4 100644 --- a/src/rougail/update.py +++ b/src/rougail/update.py @@ -23,31 +23,464 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -from typing import List -from os.path import join, isfile, basename -from os import listdir +from typing import List, Any, Optional +from os.path import join, isfile, isdir, basename +from os import listdir, makedirs from lxml.etree import DTD, parse, XMLParser, XMLSyntaxError # pylint: disable=E0611 from lxml.etree import Element, SubElement, tostring -from ast import parse as ast_parse +#from ast import parse as ast_parse +from ruamel.yaml import YAML +from json import dumps +from yaml import safe_load +from pathlib import Path from .i18n import _ from .error import UpgradeError from .utils import normalize_family from .config import RougailConfig +from .annotator.variable import CONVERT_OPTION -VERSIONS = {'creole': ['1'], - 'rougail': ['0.9', '0.10'], - } +VERSIONS = ['0.10', '1.0'] + +FIXME_PRINT_FILENAME = True +FIXME_PRINT_FILENAME = False +FIXME_PRINT_FILE = True +FIXME_PRINT_FILE = False +FIXME_PRINT_UNKNOWN_VAR = True +FIXME_PRINT_UNKNOWN_VAR = False +FIXME_PRINT_REMOVE = True +FIXME_PRINT_REMOVE = False -def get_function_name(root, version): +def get_function_name(version): version = version.replace('.', '_') - return f'update_{root}_{version}' + return f'update_{version}' -FUNCTION_VERSIONS = [(root, version, get_function_name(root, version)) for root, versions in VERSIONS.items() for version in versions] +FUNCTION_VERSIONS = [(version, get_function_name(version)) for version in VERSIONS] + + +class Unsupported(Exception): + pass + + +class upgrade_010_to_100: + def __init__(self, + dico: dict, + namespace: str, + xmlsrc: str, + ) -> None: + if FIXME_PRINT_FILE: + from pprint import pprint + pprint(dico) + self.xmlsrc = xmlsrc + self.paths = {'family': {}, 'variable': {}} + self.lists = {'service': {}, + 'ip': {}, + 'certificate': {}, + 'file': {}, + } + self.flatten_paths = {'family': {}, 'variable': {}} + self.variables = self.parse_variables(dico, namespace) + self.parse_variables_with_path() + self.parse_services(dico) + self.parse_constraints(dico) + if FIXME_PRINT_FILE: + print('==') + pprint(self.variables) + pprint(self.services) + + def parse_variables(self, + family: dict, + sub_path: str, + ) -> dict: + new_families = {} + if 'variables' in family: + for subelt in family['variables']: + for typ, obj in subelt.items(): + for subobj in obj: + getattr(self, f'convert_{typ}')(subobj, new_families, sub_path) + family.pop('variables') + return new_families + + def convert_family(self, + family: dict, + new_families: dict, + sub_path: str, + ) -> None: + # name is the key, do not let it in values + name = family.pop('name') + if sub_path: + sub_path = sub_path + '.' + name + else: + sub_path = name + # leadership and dynamic are no more attribute, it's now a type + for typ in ['leadership', 'dynamic']: + if typ in family: + value = family.pop(typ) + if value: + family['type'] = typ + # add sub families and sub variables + sub_families = self.parse_variables(family, sub_path) + for sub_name, sub_family in sub_families.copy().items(): + if sub_name not in family: + continue + family[f'_{sub_name}'] = family.pop(sub_name) + # store converted family + family.update(sub_families) + new_families[name] = family + self.flatten_paths['family'][name] = sub_path + self.paths['family'][sub_path] = family + + def convert_variable(self, + variable: dict, + new_families: dict, + sub_path: str, + ) -> dict: + name = variable.pop('name') + if sub_path: + sub_path = sub_path + '.' + name + else: + sub_path = name + new_families[name] = variable + self.flatten_paths['variable'][name] = sub_path + self.paths['variable'][sub_path] = variable + if 'remove_condition' in variable and variable.pop('remove_condition'): + if FIXME_PRINT_REMOVE: + print(f'variable {name} in file {self.xmlsrc} has remove_condition, all properties (hidden, disabled and mandatory) are set to False') + for prop in ['hidden', 'disabled', 'mandatory']: + if prop not in variable: + variable[prop] = False + if 'remove_choice' in variable: + if 'choice' not in variable: + variable['choice'] = None + variable.pop('remove_choice') + if 'remove_check' in variable: + variable.pop('remove_check') + if 'validators' not in variable: + variable['validators'] = None + if 'remove_fill' in variable: + variable.pop('remove_fill') + variable['default'] = None + + def parse_variables_with_path(self): + for variable in self.paths['variable'].values(): + if 'value' in variable: + if not variable.get('multi', False) and len(variable['value']) == 1: + #FIXME value, values? + variable['default'] = self.get_value(variable.pop('value')[0]) + else: + variable['default'] = [self.get_value(value) for value in variable.pop('value')] + if 'choice' in variable: + if not variable['choice']: + variable['choices'] = variable.pop('choice') + else: + variable['choices'] = [self.get_value(choice) for choice in variable.pop('choice')] + + def parse_services(self, + dico: dict, + ) -> None: + self.services = {} + if 'services' in dico: + for root_services in dico['services']: + for services in root_services.values(): + for service in services: + new_service = {} + for typ in ['ip', 'file', 'certificate']: + if typ != 'ip': + typ_plurial = typ + 's' + else: + typ_plurial = typ + if typ in service: + new_service[typ_plurial] = {} + for elt in service[typ]: + name, new_elt = getattr(self, f'parse_{typ}')(elt) + new_service[typ_plurial][name] = new_elt + if 'override' in service: + new_service['override'] = service['override'] + if 'servicelist' in service: + self.lists['service'].setdefault(service['servicelist'], []).append(new_service) + name = service.pop('name') + '.' + service.get('type', 'service') + self.services[name] = new_service + + def parse_ip(self, + ip: dict + ) -> None: + name = self.get_variable_path(ip.pop('text')) + if 'iplist' in ip: + self.lists['ip'].setdefault(ip.pop('iplist'), []).append(ip) + if 'netmask' in ip: + ip['netmask'] = self.get_variable_path(ip['netmask']) + return name, ip + + def parse_file(self, + file: dict + ) -> None: + name = file.pop('text') + if 'file_type' in file: + file['type'] = file.pop('file_type') + if file['type'] == 'variable': + name = self.get_variable_path(name) + if 'variable_type' in file: + file.pop('variable_type') + if 'filelist' in file: + self.lists['file'].setdefault(file.pop('filelist'), []).append(file) + for typ in ['source', 'owner', 'group']: + if f'{typ}_type' in file: + obj_type = file.pop(f'{typ}_type') + if obj_type == 'variable' and typ in file: + file[typ] = {'name': self.get_variable_path(file[typ]), + 'type': 'variable', + } + if 'variable' in file: + file['variable'] = self.get_variable_path(file['variable']) + return name, file + + def parse_certificate(self, + certificate: dict + ) -> None: + name = certificate.pop('text') + if 'certificate_type' in certificate: + certificate['type'] = certificate.pop('certificate_type') + if certificate['type'] == 'variable': + name = self.get_variable_path(name) + if 'certificatelist' in certificate: + self.lists['certificate'].setdefault(certificate.pop('certificatelist'), []).append(certificate) + for typ in ['owner', 'group', 'server', 'domain', 'provider']: + if f'{typ}_type' in certificate: + obj_type = certificate.pop(f'{typ}_type') + if obj_type == 'variable' and typ in certificate: + certificate[typ] = {'name': self.get_variable_path(certificate[typ]), + 'type': 'variable', + } + return name, certificate + + def parse_constraints(self, + dico: dict, + ) -> None: + if 'constraints' not in dico: + return + for constraint in dico['constraints']: + if 'condition' in constraint: + for condition in constraint['condition']: + self.parse_condition(condition) + if 'check' in constraint: + for check in constraint['check']: + self.parse_check(check) + if 'fill' in constraint: + for fill in constraint['fill']: + self.parse_fill(fill) + + def parse_condition(self, + condition: dict, + ) -> None: + if 'apply_on_fallback' in condition: + apply_on_fallback = condition.pop('apply_on_fallback') + else: + apply_on_fallback = False + source = self.get_variable_path(condition['source']) + if not source: + if 'optional' not in condition or not condition['optional']: + print(f'================> pffff je ne trouve pas la source {condition["source"]}') + return + elif not apply_on_fallback: + return + name = condition.pop('name') + prop = name.split('_', 1)[0] + if apply_on_fallback: + condition_value = True + else: + condition_value = self.params_condition_to_jinja(source, condition['param'], name.endswith('if_in')) + for target in condition['target']: + typ = target.get('type', 'variable') + if typ == 'variable': + variable_path = self.get_variable_path(target['text']) + if variable_path is None: + if FIXME_PRINT_UNKNOWN_VAR and not target.get('optional', False): + print(f'pffff la target {target["text"]} de la condition n\'est pas trouvable') + continue + variable = self.paths['variable'][variable_path] + variable[prop] = condition_value + elif typ == 'family': + family_path = self.get_family_path(target['text']) + if family_path is None: + if FIXME_PRINT_UNKNOWN_VAR and not target.get('optional', False): + print(f'pffff la target {target["text"]} de la condition n\'est pas trouvable') + continue + family = self.paths['family'][family_path] + family[prop] = condition_value + elif typ == 'iplist': + list_name = target['text'] + if list_name in self.lists['ip']: + for ip in self.lists['ip'].pop(list_name): + ip[prop] = condition_value + elif typ == 'filelist': + list_name = target['text'] + if list_name in self.lists['file']: + for ip in self.lists['file'].pop(list_name): + ip[prop] = condition_value + elif typ == 'servicelist': + list_name = target['text'] + if list_name in self.lists['service']: + for service in self.lists['service'].pop(list_name): + service[prop] = condition_value + elif typ == 'certificatelist': + list_name = target['text'] + if list_name in self.lists['certificate']: + for certificat in self.lists['certificate'].pop(list_name): + certificat[prop] = condition_value + + def parse_check(self, + check: dict, + ) -> None: + for target in check['target']: + variable_path = self.get_variable_path(target['text']) + if variable_path is None: + if FIXME_PRINT_UNKNOWN_VAR and not target.get('optional', False): + print(f'pffff la target {target["text"]} dans le check n\'est pas trouvable') + continue + variable = self.paths['variable'][variable_path] + if 'validators' in variable and variable['validators'] is None: + variable.pop('validators') + if check.get('type') == 'jinja': + check_value = check['name'] + else: + check['param'] = [{'text': variable_path, 'type': 'variable'}] + check.get('param', []) + check_value = self.convert_param_function(check) + variable.setdefault('validators', []).append(check_value) + + def parse_fill(self, + fill: dict, + ) -> None: + for target in fill.pop('target'): + variable_path = self.get_variable_path(target['text']) + if variable_path is None: + if FIXME_PRINT_UNKNOWN_VAR and not target.get('optional', False): + print(f'pffff la target {target["text"]} dans le fill n\'est pas trouvable') + continue + variable = self.paths['variable'][variable_path] + try: + if fill.get('type') == 'jinja': + fill_value = fill['name'] + else: + fill_value = self.convert_param_function(fill) + fill_value = {'name': fill_value, 'type': 'jinja'} + except Unsupported: + fill['type'] = 'function' + fill_value = fill + variable['default'] = fill_value + + def params_condition_to_jinja(self, + path: str, + params: List[dict], + if_in: bool, + ) -> str: + jinja = "{% if " + for idx, param in enumerate(params): + if idx: + jinja += ' or ' + + value = self.get_value(param, dump=True) + if value: + jinja += path + ' == ' + value + if if_in: + jinja += " %}true{% else %}false{% endif %}" + else: + jinja += " %}false{% else %}true{% endif %}" + if path == 'enumfam.enumvar': + print('pffff cest un number ...') + return jinja + + def get_value(self, + param: dict, + dump: bool=False, + ) -> Any: + # + typ = param.get('type', 'string') + if typ == 'string': + value = param['text'] +# value = dumps(value, ensure_ascii=False) + elif typ == 'number': + value = int(param['text']) + elif typ == 'nil': + value = None + elif typ == 'space': + value = ' ' + elif typ == 'boolean': + value = {'True': True, + 'False': False}.get(param['text']) + elif typ == 'variable': + value = {'type': 'variable', + 'value': self.get_variable_path(param['text'])} + elif typ == 'function': + value = {'type': 'jinja', + 'value': self.convert_param_function(param)} + elif typ in ['information', 'suffix', 'index']: + value = param + if dump: + if isinstance(value, dict): + if value['type'] == 'variable': + value = value['value'] + if not value: + return + else: + raise Unsupported() + else: + value = dumps(value, ensure_ascii=False) + return value + + def convert_param_function(self, + param: dict, + ) -> str: + text = param['name'] + '(' + if 'param' in param and param['param']: + first, *others = param['param'] + first = self.get_value(first, dump=True) + if isinstance(first, dict): + if first['type'] == 'variable': + first = first['value'] + else: + raise Exception('hu2?') + text = f'{first}, {text}' + if others: + params = [] + for param in others: + value = self.get_value(param, dump=True) + if param.get('type') != 'variable' or value is not None: + if 'name' in param: + params.append(f'{param["name"]}={value}') + else: + params.append(value) + params = ', '.join([self.get_value(value, dump=True) for value in others if self.get_value(value, dump=True)]) + text += ')' + return '{{ ' + text + ' }}' + + def get_variable_path(self, + path: str, + ) -> dict: + if path not in self.paths['variable'] and path in self.flatten_paths['variable']: + path = self.flatten_paths['variable'][path] + if path not in self.paths['variable']: + if FIXME_PRINT_UNKNOWN_VAR: + print('pffff impossible de trouver la variable', path) + return + return path + + def get_family_path(self, + path: str, + ) -> dict: + if path not in self.paths['family'] and path in self.flatten_paths['family']: + path = self.flatten_paths['family'][path] + if path not in self.paths['family']: + if FIXME_PRINT_UNKNOWN_VAR: + print('pffff impossible de trouver la famille', path) + return + return path + + def get(self) -> dict: + return self.variables, self.services class RougailUpgrade: @@ -64,57 +497,240 @@ class RougailUpgrade: rougailconfig = RougailConfig self.rougailconfig = rougailconfig - def load_xml_from_folders(self, - srcfolder: str, - dstfolder: str, - namespace: str, - display: bool=True, - ): - """Loads all the XML files located in the xmlfolders' list + def load_dictionaries(self, +# srcfolder: str, + dstfolder: str, + services_dstfolder: Optional[str], + extra_dstfolder: Optional[str]=None, +# namespace: str, +# display: bool=True, + ): + if extra_dstfolder is None: + extra_dstfolder = dstfolder + self._load_dictionaries(self.rougailconfig['dictionaries_dir'], + dstfolder, + services_dstfolder, + self.rougailconfig['variable_namespace'], + ) + for namespace, extra_dirs in self.rougailconfig['extra_dictionaries'].items(): + extra_dstsubfolder = join(extra_dstfolder, namespace) + if not isdir(extra_dstsubfolder): + makedirs(extra_dstsubfolder) + for extra_dir in extra_dirs: + self._load_dictionaries(extra_dir, + extra_dstsubfolder, + None, + namespace, + ) - :param xmlfolders: list of full folder's name - """ - filenames = [filename for filename in listdir(srcfolder) if filename.endswith('.xml')] + def _load_dictionaries(self, + srcfolder: str, + dstfolder: str, + services_dstfolder: Optional[str], + namespace: str, + ) -> None: + filenames = [filename for filename in listdir(srcfolder) if filename.endswith('.xml') or filename.endswith('.yml')] filenames.sort() for filename in filenames: - xmlsrc = join(srcfolder, filename) - xmldst = join(dstfolder, filename) - if isfile(xmldst): + xmlsrc = Path(srcfolder) / Path(filename) + ymlfile = filename[:-3] + 'yml' + xmldst = Path(dstfolder) / Path(ymlfile) + if xmldst.is_file(): raise Exception(f'cannot update "{xmlsrc}" destination file "{xmldst}" already exists') - try: - parser = XMLParser(remove_blank_text=True) - document = parse(xmlsrc, parser) - except XMLSyntaxError as err: - raise Exception(_(f'not a XML file: {err}')) from err - root = document.getroot() - search_function_name = get_function_name(root.tag, root.attrib.get('version', '1')) + if services_dstfolder: + ymldst_services = Path(services_dstfolder) / ymlfile + if ymldst_services.is_file(): + raise Exception(f'cannot update "{xmlsrc}" destination file "{ymldst_services}" already exists') + if filename.endswith('.xml'): + try: + parser = XMLParser(remove_blank_text=True) + document = parse(xmlsrc, parser) + except XMLSyntaxError as err: + raise Exception(_(f'not a XML file: {err}')) from err + root = document.getroot() + search_function_name = get_function_name(root.attrib.get('version', '1')) + ext = 'xml' + else: + with xmlsrc.open() as xml_fh: + root = safe_load(xml_fh) + search_function_name = get_function_name(root['version']) + ext = 'yml' function_found = False - for root_name, version, function_version in FUNCTION_VERSIONS: + if FIXME_PRINT_FILENAME: + print('========================================================================') + print(xmlsrc) + print('========================================================================') + for version, function_version in FUNCTION_VERSIONS: if function_found and hasattr(self, function_version): - if display: - print(f' - convert {filename} to version {version}') +# if display: +# print(f' - convert {filename} to version {version}') upgrade_help = self.upgrade_help.get(function_version, {}).get(filename, {}) if upgrade_help.get('remove') is True: continue - root = getattr(self, function_version)(root, upgrade_help, namespace) + root, root_services, new_type = getattr(self, function_version)(root, upgrade_help, namespace, xmlsrc, ext) if function_version == search_function_name: function_found = True - root.attrib['version'] = version - with open(xmldst, 'wb') as xmlfh: - xmlfh.write(tostring(root, pretty_print=True, encoding="UTF-8", xml_declaration=True)) - # if + if root: + root['version'] = version + xmldst.parent.mkdir(parents=True, exist_ok=True) + with xmldst.open('w') as ymlfh: + yaml = YAML() + yaml.dump(root, ymlfh) + if root_services and services_dstfolder: + root_services['version'] = version + ymldst_services.parent.mkdir(parents=True, exist_ok=True) + with ymldst_services.open('w') as ymlfh: + yaml = YAML() + yaml.dump(root_services, ymlfh) # if not self.dtd.validate(document): # dtd_error = self.dtd.error_log.filter_from_errors()[0] # msg = _(f'not a valid XML file: {dtd_error}') # raise DictConsistencyError(msg, 43, [xmlfile]) # yield xmlfile, document.getroot() + def _attribut_to_bool(self, variable): + for prop in ['mandatory', 'hidden', 'redefine', 'multi', 'leadership', 'optional', 'unique', 'auto_save', 'auto_freeze', 'remove_check', 'manage', 'exists', 'disabled', 'undisable', 'remove_choice', 'propertyerror', 'apply_on_fallback', 'remove_fill', 'remove_condition']: + if prop in variable: + variable[prop] = {'True': True, 'False': False}[variable[prop]] - def update_rougail_0_10(self, - root: 'Element', - upgrade_help: dict, - namespace: str, - ) -> 'Element': + def _attribut_to_int(self, variable): + for prop in ['mode']: + if prop in variable: + try: + variable[prop] = int(variable[prop]) + except ValueError: + pass + + def _xml_to_yaml(self, objects, obj_name, variables, path, variable_type='string', variable_choices=[]): + if obj_name in ['variables', 'family']: + dico = [] + else: + dico = {} + for obj in objects: + obj_type = obj.tag + if not isinstance(obj_type, str): + # doesn't proceed the XML commentaries + continue + new_dico = dict(obj.attrib) + if obj_type in ['variable', 'family']: + if path: + path += '.' + obj.attrib['name'] + else: + path = obj.attrib['name'] + choices = [] + if obj_type == 'variable': + var_type = obj.attrib.get('type', 'string') + variables[obj.attrib['name']]= {'type': var_type} + variables[path]= {'type': var_type} + elif obj_type == 'condition': + var_type = variables.get(obj.attrib['source'], {}).get('type', 'string') + if var_type == 'choice': + choices = variables.get(obj.attrib['source'], {}).get('choices', []) + else: + var_type = None + new_objects = self._xml_to_yaml(obj, obj.tag, variables, path, var_type, choices) + if obj.text: + text = obj.text + if isinstance(text, str): + text = text.strip() + if text: + if obj_type in ['choice', 'value']: + value_type = obj.attrib.get('type') + if not value_type and obj_type == 'value': + value_type = variable_type + text = CONVERT_OPTION.get(value_type, {}).get('func', str)(text) + if obj_type == 'choice': + variables[path.rsplit('.', 1)[-1]].setdefault('choices', []).append({'type': value_type, 'value': text}) + variables[path].setdefault('choices', []).append({'type': value_type, 'value': text}) + if obj_type in ['param', 'value']: + if obj.attrib.get('type') == 'variable': + var_type = variables.get(obj.attrib.get('name'), {}).get('type', 'string') + value_type = obj.attrib.get('type', var_type) + text = CONVERT_OPTION.get(value_type, {}).get('func', str)(text) + elif 'type' in obj.attrib: + var_type = obj.attrib.get('type') + text = CONVERT_OPTION.get(var_type, {}).get('func', str)(text) + elif obj_type == 'param' and variable_type: + if variable_type == 'choice': + for choice in variable_choices: + if choice['value'] == CONVERT_OPTION.get(choice.get('type'), {}).get('func', str)(text): + text = choice['value'] + break + else: + text = CONVERT_OPTION.get(variable_type, {}).get('func', str)(text) + new_dico['text'] = text + if isinstance(new_objects, list): + if new_objects: + for new_obj in new_objects: + new_dico.update(new_obj) + elif new_objects is not None and list(new_objects.values())[0]: + new_dico.update(new_objects) + self._attribut_to_bool(new_dico) + self._attribut_to_int(new_dico) + if not new_dico: + new_dico = None + if obj_type == 'override' and not new_dico: + new_dico = None + if isinstance(dico, list): + if dico and obj_type in dico[-1]: + dico[-1][obj_type].append(new_dico) + else: + dico.append({obj_type: [new_dico]}) + elif new_dico is None: + dico[obj_type] = new_dico + else: + dico.setdefault(obj_type, []).append(new_dico) + if dico == {}: + dico = None + elif isinstance(dico, dict): + dico = [dico] + if obj_name in ['service', 'condition', 'fill', 'choice', 'check']: + pass + elif obj_name in ['variables', 'family']: + dico = {'variables': dico} + elif obj_name != 'variable': + dico = {obj_name: dico} + return dico + + def update_1_0(self, + root: 'Element', + upgrade_help: dict, + namespace: str, + xmlsrc: str, + ext: str, + ) -> 'Element': + if ext == 'xml': + new_root = {'version': root.attrib['version']} + variables = {} + for typ in ['services', 'variables', 'constraints']: + objects = root.find(typ) + if objects is None: + objects = [] + new_objects = self._xml_to_yaml(objects, typ, variables, '') + if new_objects[typ]: + new_root.update(new_objects) +# services = root.find('services') +# if services is None: +# services = [] +# new_services = self._xml_to_yaml_service(services) +# if new_services: +# new_root['services'] = new_services +# paths = self._get_path_variables(variables, +# namespace == 'configuration', +# namespace, +# ) + else: + new_root = root + variables, services = upgrade_010_to_100(new_root, namespace, xmlsrc).get() + return variables, services, 'yml' + + def update_0_10(self, + root: 'Element', + upgrade_help: dict, + namespace: str, + xmlsrc: str, + ext: str, + ) -> 'Element': variables = root.find('variables') if variables is None: return root @@ -267,7 +883,7 @@ class RougailUpgrade: for target in targets: if 'remove_choice' not in target.attrib or target.attrib['remove_choice'] != 'True': target.attrib['type'] = 'choice' - return root + return root, None, 'xml' def _get_path_variables(self, variables, is_variable_namespace, path, dico=None): if dico is None: @@ -286,380 +902,6 @@ class RougailUpgrade: dico[subpath] = {'variable': variable, 'parent': variables} return dico - def update_rougail_0_9(self, - root: 'Element', - upgrade_help: dict, - namespace: str, - ) -> 'Element': - # rename root - root.tag = 'rougail' - variables_auto_valid_enum = {} - variables_help = {} - families_help = {} - variables = {} - families = {} - valid_enums = {} - current_service = upgrade_help.get('services', {}).get('default', 'unknown') - files = {current_service: {}} - ips = {current_service: []} - servicelists = {} - test_unknowns_variables = set() - autos = [] - constraints_obj = None - for subelement in root: - if not isinstance(subelement.tag, str): - # XML comment - continue - if subelement.tag == 'family_action': - root.remove(subelement) - continue - for subsubelement in subelement: - if not isinstance(subsubelement.tag, str): - # XML comment - continue - for subsubsubelement in subsubelement: - if not isinstance(subsubsubelement.tag, str): - # XML comment - continue - if subsubsubelement.tag == 'variable': - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - continue - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('type', {}): - subsubsubelement.attrib['type'] = upgrade_help['variables']['type'][subsubsubelement.attrib['name']] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('hidden', {}).get('add', []): - subsubsubelement.attrib['hidden'] = 'True' - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('hidden', {}).get('remove', []): - self.remove(subsubsubelement, 'hidden', optional=True) - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('mandatory', {}).get('remove', []): - self.remove(subsubsubelement, 'mandatory') - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('mandatory', {}).get('add', []): - subsubsubelement.attrib['mandatory'] = 'True' - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('type', {}): - subsubsubelement.attrib['type'] = upgrade_help.get('variables', {}).get('type', {})[subsubsubelement.attrib['name']] - if namespace == 'configuration': - path = subsubsubelement.attrib['name'] - npath = normalize_family(subsubsubelement.attrib['name']) - else: - path = namespace + '.' + subsubelement.attrib['name'] + '.' + subsubsubelement.attrib['name'] - npath = normalize_family(namespace) + '.' + normalize_family(subsubelement.attrib['name']) + '.' + normalize_family(subsubsubelement.attrib['name']) - variables[path] = subsubsubelement - variables[npath] = subsubsubelement - type = subsubsubelement.attrib.get('type') - if type in ['oui/non', 'yes/no', 'on/off']: - variables_auto_valid_enum.setdefault(subsubsubelement.attrib['type'], []).append(path) - del subsubsubelement.attrib['type'] - elif type == 'hostname_strict': - subsubsubelement.attrib['type'] = 'hostname' - elif type in ['domain', 'domain_strict']: - subsubsubelement.attrib['type'] = 'domainname' - elif type == 'string': - del subsubsubelement.attrib['type'] - if self.test and subsubsubelement.attrib.get('auto_freeze') == 'True': - del subsubsubelement.attrib['auto_freeze'] - #if self.test and subsubsubelement.attrib.get('redefine') == 'True': - # subsubsubelement.attrib['exists'] = 'False' - # del subsubsubelement.attrib['redefine'] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('redefine', {}).get('remove', {}): - del subsubsubelement.attrib['redefine'] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('remove_check', []): - subsubsubelement.attrib['remove_check'] = 'True' - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('mode', {}).get('modify', {}): - subsubsubelement.attrib['mode'] = upgrade_help.get('variables', {}).get('mode', {}).get('modify', {})[subsubsubelement.attrib['name']] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('type', {}).get('modify', {}): - subsubsubelement.attrib['type'] = upgrade_help.get('variables', {}).get('type', {}).get('modify', {})[subsubsubelement.attrib['name']] - type = subsubsubelement.attrib['type'] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('test', {}): - subsubsubelement.attrib['test'] = upgrade_help.get('variables', {}).get('test', {})[subsubsubelement.attrib['name']] - if subsubsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('remove_value', []): - for value in subsubsubelement: - subsubsubelement.remove(value) - if subsubsubelement.attrib['name'] != normalize_family(subsubsubelement.attrib['name']): - if "description" not in subsubsubelement.attrib: - subsubsubelement.attrib['description'] = subsubsubelement.attrib['name'] - subsubsubelement.attrib['name'] = normalize_family(subsubsubelement.attrib['name']) - elif subsubsubelement.tag == 'param': - if subsubelement.tag == 'check' and subsubelement.attrib['target'] in upgrade_help.get('check', {}).get('remove', []): - continue - type = subsubsubelement.attrib.get('type') - if type == 'eole': - subsubsubelement.attrib['type'] = 'variable' - type = 'variable' - if type == 'python': - subsubsubelement.attrib['type'] = 'function' - if subsubsubelement.text.startswith('range('): - func_ast = ast_parse(subsubsubelement.text) - subsubsubelement.text = 'range' - for arg in func_ast.body[0].value.args: - SubElement(subsubelement, 'param', type='number').text = str(arg.value) - else: - raise Exception(f'{subsubsubelement.text} is not a supported function') - type = 'function' - elif type in ('container', 'context'): - raise UpgradeError(_(f'cannot convert param with type "{type}"')) - if subsubelement.attrib['name'] == 'valid_entier' and not 'type' in subsubsubelement.attrib: - subsubsubelement.attrib['type'] = 'number' - if (not type or type == 'variable') and subsubsubelement.text in upgrade_help.get('variables', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - continue - if subsubelement.attrib['name'] == 'valid_enum' and not type: - if subsubsubelement.attrib.get('name') == 'checkval': - if subsubelement.attrib['target'] in upgrade_help.get('check', {}).get('valid_enums', {}).get('checkval', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - continue - raise UpgradeError(_('checkval in valid_enum is no more supported')) - if subsubsubelement.text.startswith('['): - for val in eval(subsubsubelement.text): - SubElement(subsubelement, 'param').text = str(val) - subsubelement.remove(subsubsubelement) - self.move(subsubsubelement, 'hidden', 'propertyerror', optional=True) - if type == 'variable' and subsubsubelement.text in upgrade_help.get('variables', {}).get('rename', []): - subsubsubelement.text = upgrade_help.get('variables', {}).get('rename', [])[subsubsubelement.text] - up = upgrade_help.get('params', {}).get(subsubsubelement.text) - if up: - if 'text' in up: - subsubsubelement.text = up['text'] - if 'type' in up: - subsubsubelement.attrib['type'] = up['type'] - elif subsubsubelement.tag == 'target': - type = subsubsubelement.attrib.get('type') - if type in ['service_accesslist', 'service_restrictionlist', 'interfacelist', 'hostlist']: - subsubelement.remove(subsubsubelement) - elif (not type or type == 'variable') and subsubsubelement.text in upgrade_help.get('variables', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - elif type == 'family' and subsubsubelement.text in upgrade_help.get('families', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - elif type == 'actionlist': -# for family in root.find('variables'): -# family_list = SubElement(subsubelement, 'target') -# family_list.attrib['type'] = 'family' -# family_list.text = namespace + '.' + family.attrib['name'] - subsubelement.remove(subsubsubelement) - if upgrade_help.get('targets', {}).get(subsubsubelement.text, {}).get('optional'): - subsubsubelement.attrib['optional'] = upgrade_help.get('targets', {}).get(subsubsubelement.text, {}).get('optional') - has_target = False - for target in subsubelement: - if target.tag == 'target': - has_target = True - break - if not has_target: - subelement.remove(subsubelement) - continue - elif subsubsubelement.tag == 'slave': - if subsubsubelement.text in upgrade_help.get('variables', {}).get('remove', []): - subsubelement.remove(subsubsubelement) - continue - subsubsubelement.tag = 'follower' - subsubsubelement.text = normalize_family(subsubsubelement.text) - if subelement.tag == 'containers': - current_service = self.upgrade_container(subsubsubelement, current_service, files, ips, servicelists, upgrade_help) - subsubelement.remove(subsubsubelement) - if subelement.tag == 'help': - if subsubelement.tag == 'variable': - if not subsubelement.attrib['name'] in upgrade_help.get('variables', {}).get('remove', []): - variables_help[subsubelement.attrib['name']] = subsubelement.text - elif subsubelement.tag == 'family': - if subsubelement.attrib['name'] not in upgrade_help.get('families', {}).get('remove', []): - families_help[subsubelement.attrib['name']] = subsubelement.text - else: - raise Exception(f'unknown help tag {subsubelement.tag}') - subelement.remove(subsubelement) - continue - if subsubelement.tag == 'auto': - if subsubelement.attrib['target'] in upgrade_help.get('variables', {}).get('remove', []): - subelement.remove(subsubelement) - continue - autos.append(subsubelement.attrib['target']) - subsubelement.tag = 'fill' - if subsubelement.tag in ['fill', 'check']: - if subsubelement.tag == 'check' and subsubelement.attrib['name'] == 'valid_enum': - if subsubelement.attrib['target'] in upgrade_help.get('variables', {}).get('remove', []): - subelement.remove(subsubelement) - continue - params = [] - for param in subsubelement: - if param.tag == 'param': - params.append(param.text) - key = '~'.join(params) - if key in valid_enums: - SubElement(valid_enums[key], 'target').text = subsubelement.attrib['target'] - subelement.remove(subsubelement) - continue - valid_enums['~'.join(params)] = subsubelement - if subsubelement.tag == 'fill' and subsubelement.attrib['target'] in upgrade_help.get('fills', {}).get('remove', []): - subelement.remove(subsubelement) - continue - if subsubelement.tag == 'check' and subsubelement.attrib['target'] in upgrade_help.get('check', {}).get('remove', []): - subelement.remove(subsubelement) - continue - if subsubelement.attrib['target'] in upgrade_help.get('variables', {}).get('remove', []): - subelement.remove(subsubelement) - continue - if subsubelement.attrib['name'] == 'valid_networknetmask': - subsubelement.attrib['name'] = 'valid_network_netmask' - target = SubElement(subsubelement, 'target') - target.text = subsubelement.attrib['target'] - if self.test: - target.attrib['optional'] = 'True' - del subsubelement.attrib['target'] - elif subsubelement.tag == 'separators': - subelement.remove(subsubelement) - elif subsubelement.tag == 'condition': - if subsubelement.attrib['source'] in upgrade_help.get('variables', {}).get('remove', []): - try: - subelement.remove(subsubelement) - except: - pass - else: - if subsubelement.attrib['name'] == 'hidden_if_not_in': - subsubelement.attrib['name'] = 'disabled_if_not_in' - if subsubelement.attrib['name'] == 'hidden_if_in': - subsubelement.attrib['name'] = 'disabled_if_in' - if subsubelement.attrib['name'] == 'frozen_if_in': - subsubelement.attrib['name'] = 'hidden_if_in' - self.move(subsubelement, 'fallback', 'optional', optional='True') - if subsubelement.attrib['source'] in upgrade_help.get('variables', {}).get('rename', []): - subsubelement.attrib['source'] = upgrade_help.get('variables', {}).get('rename', [])[subsubelement.attrib['source']] - elif subsubelement.tag == 'group': - if subsubelement.attrib['master'] in upgrade_help.get('groups', {}).get('remove', []): - subelement.remove(subsubelement) - else: - self.move(subsubelement, 'master', 'leader') - for follower in subsubelement: - if '.' in subsubelement.attrib['leader']: - path = subsubelement.attrib['leader'].rsplit('.', 1)[0] + '.' + follower.text - else: - path = follower.text - self.remove(variables[path], 'multi', optional=True) - if subsubelement.attrib['leader'] in upgrade_help.get('groups', {}).get('reorder', {}): - for follower in subsubelement: - subsubelement.remove(follower) - for follower in upgrade_help.get('groups', {}).get('reorder', {})[subsubelement.attrib['leader']]: - SubElement(subsubelement, 'follower').text = follower - if subelement.tag == 'files': - current_service = self.upgrade_container(subsubelement, current_service, files, ips, servicelists, upgrade_help) - subelement.remove(subsubelement) - if subsubelement.tag == 'family': - self.remove(subsubelement, 'icon', optional=True) - if subsubelement.attrib['name'] in upgrade_help.get('families', {}).get('mode', {}).get('remove', []) and 'mode' in subsubelement.attrib: - del subsubelement.attrib['mode'] - if subsubelement.attrib['name'] in upgrade_help.get('families', {}).get('rename', {}): - subsubelement.attrib['name'] = upgrade_help.get('families', {}).get('rename', {})[subsubelement.attrib['name']] - if subsubelement.attrib['name'] in upgrade_help.get('families', {}).get('remove', []): - subelement.remove(subsubelement) - continue - if subsubelement.attrib['name'] in upgrade_help.get('families', {}).get('hidden', {}).get('add', []): - subsubelement.attrib['hidden'] = 'True' - if subsubelement.attrib['name'] != normalize_family(subsubelement.attrib['name']): - if "description" not in subsubelement.attrib: - subsubelement.attrib['description'] = subsubelement.attrib['name'] - subsubelement.attrib['name'] = normalize_family(subsubelement.attrib['name']) - families[subsubelement.attrib['name']] = subsubelement - # if empty, remove - if is_empty(subelement) or subelement.tag in ['containers', 'files', 'help']: - root.remove(subelement) - continue - # copy subelement - if subelement.tag == 'constraints': - constraints_obj = subelement - services = None - service_elt = {} - for variable, obj in upgrade_help.get('variables', {}).get('add', {}).items(): - family = next(iter(families.values())) - variables[variable] = SubElement(family, 'variable', name=variable) - if 'value' in obj: - SubElement(variables[variable], 'value').text = obj['value'] - for name in ['hidden', 'exists']: - if name in obj: - variables[variable].attrib[name] = obj[name] - files_is_empty = True - for lst in files.values(): - if len(lst): - files_is_empty = False - break - if not files_is_empty: - services = Element('services') - root.insert(0, services) - for service_name, lst in files.items(): - service = self.create_service(services, service_name, service_elt, servicelists, upgrade_help) - for file_ in lst.values(): - self.move(file_, 'name_type', 'file_type', optional=True) - if 'file_type' in file_.attrib and file_.attrib['file_type'] == 'SymLinkOption': - file_.attrib['file_type'] = 'variable' - if variables[file_.text].attrib['type'] == 'string': - variables[file_.text].attrib['type'] = 'filename' - self.remove(file_, 'rm', optional=True) - self.remove(file_, 'mkdir', optional=True) - service.append(file_) - ips_is_empty = True - for lst in ips.values(): - if len(lst): - ips_is_empty = False - break - if not ips_is_empty: - if services is None: - services = Element('services') - root.insert(0, services) - for service_name, lst in ips.items(): - service = self.create_service(services, service_name, service_elt, servicelists, upgrade_help) - for ip in lst: - if ip.text in upgrade_help.get('ips', {}).get('remove', []): - continue - for type in ['ip_type', 'netmask_type']: - if type in ip.attrib and ip.attrib[type] == 'SymLinkOption': - ip.attrib[type] = 'variable' - if 'netmask' in ip.attrib: - if ip.attrib['netmask'] == '255.255.255.255': - del ip.attrib['netmask'] - if ip.text in variables and 'type' not in variables[ip.text].attrib: - variables[ip.text].attrib['type'] = 'ip' - else: - if ip.text in variables and 'type' not in variables[ip.text].attrib: - variables[ip.text].attrib['type'] = 'network' - if ip.attrib['netmask'] in variables and 'type' not in variables[ip.attrib['netmask']].attrib: - variables[ip.attrib['netmask']].attrib['type'] = 'netmask' - elif ip.text in variables and 'type' not in variables[ip.text].attrib: - variables[ip.text].attrib['type'] = 'ip' - self.remove(ip, 'interface') - self.remove(ip, 'interface_type', optional=True) - self.remove(ip, 'service_restrictionlist', optional=True) - service.append(ip) - if ips_is_empty and files_is_empty: - for service_name in files: - if services is None: - services = Element('services') - root.insert(0, services) - if service_name != 'unknown': - self.create_service(services, service_name, service_elt, servicelists, upgrade_help) - if constraints_obj is None: - constraints_obj = SubElement(root, 'constraints') - if variables_auto_valid_enum: - for type, variables_valid_enum in variables_auto_valid_enum.items(): - valid_enum = SubElement(constraints_obj, 'check') - valid_enum.attrib['name'] = 'valid_enum' - for val in type.split('/'): - param = SubElement(valid_enum, 'param') - param.text = val - for variable in variables_valid_enum: - target = SubElement(valid_enum, 'target') - target.text = variable - for name, text in variables_help.items(): - variables[name].attrib['help'] = text - for name, text in families_help.items(): - if name in upgrade_help.get('families', {}).get('rename', {}): - name = upgrade_help.get('families', {}).get('rename', {})[name] - families[normalize_family(name)].attrib['help'] = text - for auto in autos: - if auto in variables: - variables[auto].attrib['hidden'] = 'True' - else: - # redefine value in first family - family = next(iter(families.values())) - variable = SubElement(family, 'variable', name=auto, redefine="True", hidden="True") - if self.test: - del variable.attrib['redefine'] - return root - @staticmethod def move(elt, src, dst, optional=False): if src == 'text': @@ -699,7 +941,7 @@ class RougailUpgrade: service.attrib['servicelist'] = servicelists[service_name] return service - def upgrade_container(self, elt, current_service, files, ips, servicelists, upgrade_help): + def upgrade_container(self, elt, current_service, files, ip, servicelists, upgrade_help): if elt.tag == 'file': self.move(elt, 'name', 'text') self.remove(elt, 'del_comment', optional=True) @@ -726,11 +968,11 @@ class RougailUpgrade: elt_service = upgrade_help.get('services', {}).get('rename', {})[elt.attrib['service']] else: elt_service = elt.attrib['service'] - if elt_service in ips: + if elt_service in ip: service = elt_service else: service = current_service - ips[service].append(restriction) + ip[service].append(restriction) elif elt.tag == 'service': new_name = elt.text if current_service == 'unknown': @@ -738,27 +980,14 @@ class RougailUpgrade: raise Exception('hu?') files[new_name] = files[current_service] del files[current_service] - ips[new_name] = ips[current_service] - del ips[current_service] + ip[new_name] = ip[current_service] + del ip[current_service] elif new_name not in files: files[new_name] = {} - ips[new_name] = [] + ip[new_name] = [] current_service = new_name if 'servicelist' in elt.attrib: servicelists[current_service] = elt.attrib['servicelist'] else: raise Exception(f'unknown containers tag {elt.tag}') return current_service - - -def is_empty(elt, not_check_attrib=False): - if not not_check_attrib and elt.attrib: - return False - empty = True - for file_ in elt: - empty = False - return empty - - -def update_creole_1(): - print('pfff') diff --git a/tests/dictionaries_old/00empty/00_base.xml b/tests/dictionaries_old/00empty/00_base.xml deleted file mode 100644 index 78227d6fc..000000000 --- a/tests/dictionaries_old/00empty/00_base.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/tests/dictionaries_old/00empty/makedict/after.json b/tests/dictionaries_old/00empty/makedict/after.json index fd94145f9..9cd2d3dde 100644 --- a/tests/dictionaries_old/00empty/makedict/after.json +++ b/tests/dictionaries_old/00empty/makedict/after.json @@ -1,9 +1,9 @@ { - "services.tata.activate": { + "services.tata_service.activate": { "owner": "default", "value": true }, - "services.tata.manage": { + "services.tata_service.manage": { "owner": "default", "value": true } diff --git a/tests/dictionaries_old/00empty/makedict/base.json b/tests/dictionaries_old/00empty/makedict/base.json index df4366ea1..2bcec6972 100644 --- a/tests/dictionaries_old/00empty/makedict/base.json +++ b/tests/dictionaries_old/00empty/makedict/base.json @@ -1,4 +1,4 @@ { - "services.tata.activate": true, - "services.tata.manage": true + "services.tata_service.activate": true, + "services.tata_service.manage": true } diff --git a/tests/dictionaries_old/00empty/makedict/before.json b/tests/dictionaries_old/00empty/makedict/before.json index fd94145f9..9cd2d3dde 100644 --- a/tests/dictionaries_old/00empty/makedict/before.json +++ b/tests/dictionaries_old/00empty/makedict/before.json @@ -1,9 +1,9 @@ { - "services.tata.activate": { + "services.tata_service.activate": { "owner": "default", "value": true }, - "services.tata.manage": { + "services.tata_service.manage": { "owner": "default", "value": true } diff --git a/tests/dictionaries_old/00empty/result/services/00_base.yml b/tests/dictionaries_old/00empty/result/services/00_base.yml new file mode 100644 index 000000000..c68a20606 --- /dev/null +++ b/tests/dictionaries_old/00empty/result/services/00_base.yml @@ -0,0 +1,2 @@ +tata.service: {} +version: '1.0' diff --git a/tests/dictionaries_old/00empty/tiramisu/base.py b/tests/dictionaries_old/00empty/tiramisu/base.py index b91f13551..652389f75 100644 --- a/tests/dictionaries_old/00empty/tiramisu/base.py +++ b/tests/dictionaries_old/00empty/tiramisu/base.py @@ -1,18 +1,31 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") option_3 = BoolOption(name="activate", doc="activate", default=True) option_4 = BoolOption(name="manage", doc="manage", default=True) -option_2 = OptionDescription(name="tata", doc="tata", children=[option_3, option_4]) -option_1 = OptionDescription(name="services", doc="services", children=[option_2], properties=frozenset({"hidden"})) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) +optiondescription_2 = OptionDescription(name="tata_service", doc="tata_service", children=[option_3, option_4]) +optiondescription_2.impl_set_information('type', "service") +optiondescription_1 = OptionDescription(name="services", doc="services", children=[optiondescription_2], properties=frozenset({"hidden", "normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00empty/tiramisu/multi.py b/tests/dictionaries_old/00empty/tiramisu/multi.py new file mode 100644 index 000000000..8a3dd5d53 --- /dev/null +++ b/tests/dictionaries_old/00empty/tiramisu/multi.py @@ -0,0 +1,38 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_1 = BoolOption(name="activate", doc="activate", default=True) +option_2 = BoolOption(name="manage", doc="manage", default=True) +optiondescription_7 = OptionDescription(name="tata_service", doc="tata.service", children=[option_1, option_2]) +optiondescription_7.impl_set_information('type', "service") +optiondescription_6 = OptionDescription(name="services", doc="services", children=[optiondescription_7], properties=frozenset({"hidden"})) +optiondescription_5 = OptionDescription(name="1", doc="1", children=[optiondescription_6]) +option_3 = BoolOption(name="activate", doc="activate", default=True) +option_4 = BoolOption(name="manage", doc="manage", default=True) +optiondescription_10 = OptionDescription(name="tata_service", doc="tata.service", children=[option_3, option_4]) +optiondescription_10.impl_set_information('type', "service") +optiondescription_9 = OptionDescription(name="services", doc="services", children=[optiondescription_10], properties=frozenset({"hidden"})) +optiondescription_8 = OptionDescription(name="2", doc="2", children=[optiondescription_9]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_5, optiondescription_8]) diff --git a/tests/dictionaries_old/00empty/xml/00_base.xml b/tests/dictionaries_old/00empty/xml/00_base.xml new file mode 100644 index 000000000..17be1b823 --- /dev/null +++ b/tests/dictionaries_old/00empty/xml/00_base.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/dictionaries_old/00empty/yml/00_base.yml b/tests/dictionaries_old/00empty/yml/00_base.yml new file mode 100644 index 000000000..ee6a3f5c6 --- /dev/null +++ b/tests/dictionaries_old/00empty/yml/00_base.yml @@ -0,0 +1,4 @@ +version: '0.10' +services: +- service: + - name: tata diff --git a/tests/dictionaries_old/00load_autofreeze/00-base.xml b/tests/dictionaries_old/00load_autofreeze/00-base.xml deleted file mode 100644 index 92f639a10..000000000 --- a/tests/dictionaries_old/00load_autofreeze/00-base.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - no - - - False - - - diff --git a/tests/dictionaries_old/00load_autofreeze/result/rougail/00-base.yml b/tests/dictionaries_old/00load_autofreeze/result/rougail/00-base.yml new file mode 100644 index 000000000..9ad7cb8fa --- /dev/null +++ b/tests/dictionaries_old/00load_autofreeze/result/rougail/00-base.yml @@ -0,0 +1,7 @@ +myvar: + auto_freeze: true + default: no +server_deployed: + type: boolean + default: false +version: '1.0' diff --git a/tests/dictionaries_old/00load_autofreeze/tiramisu/base.py b/tests/dictionaries_old/00load_autofreeze/tiramisu/base.py index d9e1aeff5..4b692aed6 100644 --- a/tests/dictionaries_old/00load_autofreeze/tiramisu/base.py +++ b/tests/dictionaries_old/00load_autofreeze/tiramisu/base.py @@ -1,17 +1,29 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * -option_3 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) -option_2 = StrOption(name="myvar", doc="myvar", default="no", properties=frozenset({"basic", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_3, todict=True, notraisepropertyerror=True), 'expected': ParamValue(True)}))})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="myvar", doc="myvar", default=False, properties=frozenset({"basic"})) +option_3 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_autofreeze/tiramisu/multi.py b/tests/dictionaries_old/00load_autofreeze/tiramisu/multi.py new file mode 100644 index 000000000..cce87cd7e --- /dev/null +++ b/tests/dictionaries_old/00load_autofreeze/tiramisu/multi.py @@ -0,0 +1,34 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) +option_1 = StrOption(name="myvar", doc="myvar", default="no", properties=frozenset({"basic", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_2, notraisepropertyerror=True), 'expected': ParamValue(True)}), func.calc_value_property_help)})) +optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", children=[option_1, option_2], properties=frozenset({"basic"})) +optiondescription_5 = OptionDescription(name="1", doc="1", children=[optiondescription_6]) +option_4 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) +option_3 = StrOption(name="myvar", doc="myvar", default="no", properties=frozenset({"basic", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_4, notraisepropertyerror=True), 'expected': ParamValue(True)}), func.calc_value_property_help)})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[option_3, option_4], properties=frozenset({"basic"})) +optiondescription_7 = OptionDescription(name="2", doc="2", children=[optiondescription_8]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_5, optiondescription_7]) diff --git a/tests/dictionaries_old/00load_autofreeze/xml/00-base.xml b/tests/dictionaries_old/00load_autofreeze/xml/00-base.xml new file mode 100644 index 000000000..96d545532 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreeze/xml/00-base.xml @@ -0,0 +1,11 @@ + + + + + no + + + False + + + diff --git a/tests/dictionaries_old/00load_autofreeze/yml/00-base.yml b/tests/dictionaries_old/00load_autofreeze/yml/00-base.yml new file mode 100644 index 000000000..c42e2e729 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreeze/yml/00-base.yml @@ -0,0 +1,11 @@ +version: '0.10' +variables: +- variable: + - name: myvar + auto_freeze: true + value: + - text: 'no' + - name: server_deployed + type: boolean + value: + - text: false diff --git a/tests/dictionaries_old/00load_autofreezeexpert/00-base.xml b/tests/dictionaries_old/00load_autofreezeexpert/00-base.xml deleted file mode 100644 index 5c1546e2d..000000000 --- a/tests/dictionaries_old/00load_autofreezeexpert/00-base.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - no - - - False - - - diff --git a/tests/dictionaries_old/00load_autofreezeexpert/result/rougail/00-base.yml b/tests/dictionaries_old/00load_autofreezeexpert/result/rougail/00-base.yml new file mode 100644 index 000000000..310823270 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreezeexpert/result/rougail/00-base.yml @@ -0,0 +1,8 @@ +my_var: + auto_freeze: true + mode: expert + default: no +server_deployed: + type: boolean + default: false +version: '1.0' diff --git a/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/base.py b/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/base.py index b742e378b..b42b8acd9 100644 --- a/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/base.py +++ b/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/base.py @@ -1,17 +1,29 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * -option_3 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) -option_2 = StrOption(name="my_var", doc="my_var", default="no", properties=frozenset({"expert", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_3, todict=True, notraisepropertyerror=True), 'expected': ParamValue(True)}))})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="my_var", doc="my_var", default=False, properties=frozenset({"expert"})) +option_3 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/multi.py b/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/multi.py new file mode 100644 index 000000000..c195fb228 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreezeexpert/tiramisu/multi.py @@ -0,0 +1,34 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) +option_1 = StrOption(name="my_var", doc="my_var", default="no", properties=frozenset({"expert", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_2, notraisepropertyerror=True), 'expected': ParamValue(True)}), func.calc_value_property_help)})) +optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", children=[option_1, option_2], properties=frozenset({"normal"})) +optiondescription_5 = OptionDescription(name="1", doc="1", children=[optiondescription_6]) +option_4 = BoolOption(name="server_deployed", doc="server_deployed", default=False, properties=frozenset({"mandatory", "normal"})) +option_3 = StrOption(name="my_var", doc="my_var", default="no", properties=frozenset({"expert", "force_store_value", "mandatory", Calculation(func.calc_value, Params(ParamValue('frozen'), kwargs={'condition': ParamOption(option_4, notraisepropertyerror=True), 'expected': ParamValue(True)}), func.calc_value_property_help)})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[option_3, option_4], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="2", doc="2", children=[optiondescription_8]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_5, optiondescription_7]) diff --git a/tests/dictionaries_old/00load_autofreezeexpert/xml/00-base.xml b/tests/dictionaries_old/00load_autofreezeexpert/xml/00-base.xml new file mode 100644 index 000000000..7b8fbc534 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreezeexpert/xml/00-base.xml @@ -0,0 +1,11 @@ + + + + + no + + + False + + + diff --git a/tests/dictionaries_old/00load_autofreezeexpert/yml/00-base.yml b/tests/dictionaries_old/00load_autofreezeexpert/yml/00-base.yml new file mode 100644 index 000000000..f1f146461 --- /dev/null +++ b/tests/dictionaries_old/00load_autofreezeexpert/yml/00-base.yml @@ -0,0 +1,12 @@ +version: '0.10' +variables: +- variable: + - name: my_var + auto_freeze: true + mode: expert + value: + - text: 'no' + - name: server_deployed + type: boolean + value: + - text: false diff --git a/tests/dictionaries_old/00load_autosave/00-base.xml b/tests/dictionaries_old/00load_autosave/00-base.xml deleted file mode 100644 index 647c823d7..000000000 --- a/tests/dictionaries_old/00load_autosave/00-base.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - non - - - - diff --git a/tests/dictionaries_old/00load_autosave/result/rougail/00-base.yml b/tests/dictionaries_old/00load_autosave/result/rougail/00-base.yml new file mode 100644 index 000000000..d0c8eeb01 --- /dev/null +++ b/tests/dictionaries_old/00load_autosave/result/rougail/00-base.yml @@ -0,0 +1,10 @@ +server_deployed: + type: boolean +general: + description: général + mode_conteneur_actif: + type: string + description: No change + auto_save: true + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_autosave/tiramisu/base.py b/tests/dictionaries_old/00load_autosave/tiramisu/base.py index 6f6f426e6..a930c6d8e 100644 --- a/tests/dictionaries_old/00load_autosave/tiramisu/base.py +++ b/tests/dictionaries_old/00load_autosave/tiramisu/base.py @@ -1,18 +1,30 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * -option_2 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) -option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"basic", "force_store_value", "mandatory"})) -option_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"basic"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = BoolOption(name="server_deployed", doc="server_deployed", properties=frozenset({"normal"})) +option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"basic", "mandatory"})) +optiondescription_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"basic"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, optiondescription_3], properties=frozenset({"basic"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_autosave/tiramisu/multi.py b/tests/dictionaries_old/00load_autosave/tiramisu/multi.py new file mode 100644 index 000000000..1f0bbe68e --- /dev/null +++ b/tests/dictionaries_old/00load_autosave/tiramisu/multi.py @@ -0,0 +1,36 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_1 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) +option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"basic", "force_store_value", "mandatory"})) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"basic"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[option_1, optiondescription_2], properties=frozenset({"basic"})) +optiondescription_7 = OptionDescription(name="1", doc="1", children=[optiondescription_8]) +option_4 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) +option_6 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"basic", "force_store_value", "mandatory"})) +optiondescription_5 = OptionDescription(name="general", doc="général", children=[option_6], properties=frozenset({"basic"})) +optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", children=[option_4, optiondescription_5], properties=frozenset({"basic"})) +optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_7, optiondescription_9]) diff --git a/tests/dictionaries_old/00load_autosave/xml/00-base.xml b/tests/dictionaries_old/00load_autosave/xml/00-base.xml new file mode 100644 index 000000000..731c00e56 --- /dev/null +++ b/tests/dictionaries_old/00load_autosave/xml/00-base.xml @@ -0,0 +1,11 @@ + + + + + + + non + + + + diff --git a/tests/dictionaries_old/00load_autosave/yml/00-base.yml b/tests/dictionaries_old/00load_autosave/yml/00-base.yml new file mode 100644 index 000000000..f68705312 --- /dev/null +++ b/tests/dictionaries_old/00load_autosave/yml/00-base.yml @@ -0,0 +1,16 @@ +version: '0.10' +variables: +- variable: + - name: server_deployed + type: boolean +- family: + - name: general + description: "g\xE9n\xE9ral" + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: No change + auto_save: true + value: + - text: non diff --git a/tests/dictionaries_old/00load_autosaveexpert/00-base.xml b/tests/dictionaries_old/00load_autosaveexpert/00-base.xml deleted file mode 100644 index 2959c5c30..000000000 --- a/tests/dictionaries_old/00load_autosaveexpert/00-base.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - non - - - - diff --git a/tests/dictionaries_old/00load_autosaveexpert/result/rougail/00-base.yml b/tests/dictionaries_old/00load_autosaveexpert/result/rougail/00-base.yml new file mode 100644 index 000000000..6bed2dd57 --- /dev/null +++ b/tests/dictionaries_old/00load_autosaveexpert/result/rougail/00-base.yml @@ -0,0 +1,11 @@ +server_deployed: + type: boolean +general: + description: général + mode_conteneur_actif: + type: string + description: No change + auto_save: true + mode: expert + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_autosaveexpert/tiramisu/base.py b/tests/dictionaries_old/00load_autosaveexpert/tiramisu/base.py index 285bb10b3..f2aa40be8 100644 --- a/tests/dictionaries_old/00load_autosaveexpert/tiramisu/base.py +++ b/tests/dictionaries_old/00load_autosaveexpert/tiramisu/base.py @@ -1,18 +1,30 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * -option_2 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) -option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "force_store_value", "mandatory"})) -option_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"expert"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, option_3]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = BoolOption(name="server_deployed", doc="server_deployed", properties=frozenset({"normal"})) +option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "mandatory"})) +optiondescription_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"expert"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2, optiondescription_3], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_autosaveexpert/tiramisu/multi.py b/tests/dictionaries_old/00load_autosaveexpert/tiramisu/multi.py new file mode 100644 index 000000000..8a431ec4e --- /dev/null +++ b/tests/dictionaries_old/00load_autosaveexpert/tiramisu/multi.py @@ -0,0 +1,36 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_1 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) +option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "force_store_value", "mandatory"})) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"expert"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[option_1, optiondescription_2], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="1", doc="1", children=[optiondescription_8]) +option_4 = BoolOption(name="server_deployed", doc="server_deployed", default=True, properties=frozenset({"mandatory", "normal"})) +option_6 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"expert", "force_store_value", "mandatory"})) +optiondescription_5 = OptionDescription(name="general", doc="général", children=[option_6], properties=frozenset({"expert"})) +optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", children=[option_4, optiondescription_5], properties=frozenset({"normal"})) +optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_7, optiondescription_9]) diff --git a/tests/dictionaries_old/00load_autosaveexpert/xml/00-base.xml b/tests/dictionaries_old/00load_autosaveexpert/xml/00-base.xml new file mode 100644 index 000000000..a4e833da3 --- /dev/null +++ b/tests/dictionaries_old/00load_autosaveexpert/xml/00-base.xml @@ -0,0 +1,11 @@ + + + + + + + non + + + + diff --git a/tests/dictionaries_old/00load_autosaveexpert/yml/00-base.yml b/tests/dictionaries_old/00load_autosaveexpert/yml/00-base.yml new file mode 100644 index 000000000..7c6409deb --- /dev/null +++ b/tests/dictionaries_old/00load_autosaveexpert/yml/00-base.yml @@ -0,0 +1,17 @@ +version: '0.10' +variables: +- variable: + - name: server_deployed + type: boolean +- family: + - name: general + description: "g\xE9n\xE9ral" + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: No change + auto_save: true + mode: expert + value: + - text: non diff --git a/tests/dictionaries_old/00load_comment/00-base.xml b/tests/dictionaries_old/00load_comment/00-base.xml deleted file mode 100644 index 7ff4428fe..000000000 --- a/tests/dictionaries_old/00load_comment/00-base.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - diff --git a/tests/dictionaries_old/00load_comment/result/rougail/00-base.yml b/tests/dictionaries_old/00load_comment/result/rougail/00-base.yml new file mode 100644 index 000000000..1085cc1cc --- /dev/null +++ b/tests/dictionaries_old/00load_comment/result/rougail/00-base.yml @@ -0,0 +1,8 @@ +general: + description: général + mode_conteneur_actif: + type: string + description: No change + hidden: true + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_comment/tiramisu/base.py b/tests/dictionaries_old/00load_comment/tiramisu/base.py index 90d2f6309..f60bf8c84 100644 --- a/tests/dictionaries_old/00load_comment/tiramisu/base.py +++ b/tests/dictionaries_old/00load_comment/tiramisu/base.py @@ -1,17 +1,29 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) -option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[optiondescription_2], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_comment/tiramisu/multi.py b/tests/dictionaries_old/00load_comment/tiramisu/multi.py new file mode 100644 index 000000000..6428e06da --- /dev/null +++ b/tests/dictionaries_old/00load_comment/tiramisu/multi.py @@ -0,0 +1,34 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="général", children=[option_2], properties=frozenset({"normal"})) +optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1], properties=frozenset({"normal"})) +optiondescription_5 = OptionDescription(name="1", doc="1", children=[optiondescription_6]) +option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"normal"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_3], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="2", doc="2", children=[optiondescription_8]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_5, optiondescription_7]) diff --git a/tests/dictionaries_old/00load_comment/xml/00-base.xml b/tests/dictionaries_old/00load_comment/xml/00-base.xml new file mode 100644 index 000000000..6ac1ab457 --- /dev/null +++ b/tests/dictionaries_old/00load_comment/xml/00-base.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/tests/dictionaries_old/00load_comment/yml/00-base.yml b/tests/dictionaries_old/00load_comment/yml/00-base.yml new file mode 100644 index 000000000..862ba9941 --- /dev/null +++ b/tests/dictionaries_old/00load_comment/yml/00-base.yml @@ -0,0 +1,13 @@ +version: '0.10' +variables: +- family: + - name: general + description: "g\xE9n\xE9ral" + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: No change + hidden: true + value: + - text: non diff --git a/tests/dictionaries_old/00load_notype/00-base.xml b/tests/dictionaries_old/00load_notype/00-base.xml deleted file mode 100644 index 14c82f1ca..000000000 --- a/tests/dictionaries_old/00load_notype/00-base.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - non - - - - diff --git a/tests/dictionaries_old/00load_notype/result/rougail/00-base.yml b/tests/dictionaries_old/00load_notype/result/rougail/00-base.yml new file mode 100644 index 000000000..1355fc8a8 --- /dev/null +++ b/tests/dictionaries_old/00load_notype/result/rougail/00-base.yml @@ -0,0 +1,10 @@ +general: + description: général + mode_conteneur_actif: + type: string + description: No change + hidden: true + default: non + without_type: + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_notype/tiramisu/base.py b/tests/dictionaries_old/00load_notype/tiramisu/base.py index 77bf46518..2cafc2dcb 100644 --- a/tests/dictionaries_old/00load_notype/tiramisu/base.py +++ b/tests/dictionaries_old/00load_notype/tiramisu/base.py @@ -1,18 +1,30 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) option_4 = StrOption(name="without_type", doc="without_type", default="non", properties=frozenset({"mandatory", "normal"})) -option_2 = OptionDescription(name="general", doc="général", children=[option_3, option_4], properties=frozenset({"normal"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3, option_4], properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[optiondescription_2], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_notype/tiramisu/multi.py b/tests/dictionaries_old/00load_notype/tiramisu/multi.py new file mode 100644 index 000000000..e26761811 --- /dev/null +++ b/tests/dictionaries_old/00load_notype/tiramisu/multi.py @@ -0,0 +1,36 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +option_3 = StrOption(name="without_type", doc="without_type", default="non", properties=frozenset({"mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="général", children=[option_2, option_3], properties=frozenset({"normal"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="1", doc="1", children=[optiondescription_8]) +option_5 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +option_6 = StrOption(name="without_type", doc="without_type", default="non", properties=frozenset({"mandatory", "normal"})) +optiondescription_4 = OptionDescription(name="general", doc="général", children=[option_5, option_6], properties=frozenset({"normal"})) +optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_4], properties=frozenset({"normal"})) +optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_7, optiondescription_9]) diff --git a/tests/dictionaries_old/00load_notype/xml/00-base.xml b/tests/dictionaries_old/00load_notype/xml/00-base.xml new file mode 100644 index 000000000..6594e9397 --- /dev/null +++ b/tests/dictionaries_old/00load_notype/xml/00-base.xml @@ -0,0 +1,13 @@ + + + + + + + non + + + + diff --git a/tests/dictionaries_old/00load_notype/yml/00-base.yml b/tests/dictionaries_old/00load_notype/yml/00-base.yml new file mode 100644 index 000000000..57dfc3a38 --- /dev/null +++ b/tests/dictionaries_old/00load_notype/yml/00-base.yml @@ -0,0 +1,16 @@ +version: '0.10' +variables: +- family: + - name: general + description: "g\xE9n\xE9ral" + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: No change + hidden: true + value: + - text: non + - name: without_type + value: + - text: non diff --git a/tests/dictionaries_old/00load_save/00-base.xml b/tests/dictionaries_old/00load_save/00-base.xml deleted file mode 100644 index 849130906..000000000 --- a/tests/dictionaries_old/00load_save/00-base.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/tests/dictionaries_old/00load_save/result/rougail/00-base.yml b/tests/dictionaries_old/00load_save/result/rougail/00-base.yml new file mode 100644 index 000000000..1085cc1cc --- /dev/null +++ b/tests/dictionaries_old/00load_save/result/rougail/00-base.yml @@ -0,0 +1,8 @@ +general: + description: général + mode_conteneur_actif: + type: string + description: No change + hidden: true + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_save/tiramisu/base.py b/tests/dictionaries_old/00load_save/tiramisu/base.py index 90d2f6309..f60bf8c84 100644 --- a/tests/dictionaries_old/00load_save/tiramisu/base.py +++ b/tests/dictionaries_old/00load_save/tiramisu/base.py @@ -1,17 +1,29 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) -option_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[optiondescription_2], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_save/tiramisu/multi.py b/tests/dictionaries_old/00load_save/tiramisu/multi.py new file mode 100644 index 000000000..6428e06da --- /dev/null +++ b/tests/dictionaries_old/00load_save/tiramisu/multi.py @@ -0,0 +1,34 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="général", children=[option_2], properties=frozenset({"normal"})) +optiondescription_6 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1], properties=frozenset({"normal"})) +optiondescription_5 = OptionDescription(name="1", doc="1", children=[optiondescription_6]) +option_4 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_3 = OptionDescription(name="general", doc="général", children=[option_4], properties=frozenset({"normal"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_3], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="2", doc="2", children=[optiondescription_8]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_5, optiondescription_7]) diff --git a/tests/dictionaries_old/00load_save/xml/00-base.xml b/tests/dictionaries_old/00load_save/xml/00-base.xml new file mode 100644 index 000000000..f0576995a --- /dev/null +++ b/tests/dictionaries_old/00load_save/xml/00-base.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/tests/dictionaries_old/00load_save/yml/00-base.yml b/tests/dictionaries_old/00load_save/yml/00-base.yml new file mode 100644 index 000000000..862ba9941 --- /dev/null +++ b/tests/dictionaries_old/00load_save/yml/00-base.yml @@ -0,0 +1,13 @@ +version: '0.10' +variables: +- family: + - name: general + description: "g\xE9n\xE9ral" + variables: + - variable: + - name: mode_conteneur_actif + type: string + description: No change + hidden: true + value: + - text: non diff --git a/tests/dictionaries_old/00load_subfolder/makedict/after.json b/tests/dictionaries_old/00load_subfolder/makedict/after.json index 6ebfbbe96..39ed60d03 100644 --- a/tests/dictionaries_old/00load_subfolder/makedict/after.json +++ b/tests/dictionaries_old/00load_subfolder/makedict/after.json @@ -1,9 +1,9 @@ { - "rougail.general.mode_conteneur_actif": { + "rougail.general.mode_conteneur_actif1": { "owner": "default", "value": "non" }, - "rougail.general.mode_conteneur_actif1": { + "rougail.general.mode_conteneur_actif": { "owner": "default", "value": "non" } diff --git a/tests/dictionaries_old/00load_subfolder/makedict/base.json b/tests/dictionaries_old/00load_subfolder/makedict/base.json index 3f1a7b004..fb54e4386 100644 --- a/tests/dictionaries_old/00load_subfolder/makedict/base.json +++ b/tests/dictionaries_old/00load_subfolder/makedict/base.json @@ -1,4 +1,4 @@ { - "rougail.general.mode_conteneur_actif": "non", - "rougail.general.mode_conteneur_actif1": "non" + "rougail.general.mode_conteneur_actif1": "non", + "rougail.general.mode_conteneur_actif": "non" } diff --git a/tests/dictionaries_old/00load_subfolder/makedict/before.json b/tests/dictionaries_old/00load_subfolder/makedict/before.json index 6ebfbbe96..39ed60d03 100644 --- a/tests/dictionaries_old/00load_subfolder/makedict/before.json +++ b/tests/dictionaries_old/00load_subfolder/makedict/before.json @@ -1,9 +1,9 @@ { - "rougail.general.mode_conteneur_actif": { + "rougail.general.mode_conteneur_actif1": { "owner": "default", "value": "non" }, - "rougail.general.mode_conteneur_actif1": { + "rougail.general.mode_conteneur_actif": { "owner": "default", "value": "non" } diff --git a/tests/dictionaries_old/00load_subfolder/result/rougail/99-base.yml b/tests/dictionaries_old/00load_subfolder/result/rougail/99-base.yml new file mode 100644 index 000000000..1085cc1cc --- /dev/null +++ b/tests/dictionaries_old/00load_subfolder/result/rougail/99-base.yml @@ -0,0 +1,8 @@ +general: + description: général + mode_conteneur_actif: + type: string + description: No change + hidden: true + default: non +version: '1.0' diff --git a/tests/dictionaries_old/00load_subfolder/subfolder/00-base.xml b/tests/dictionaries_old/00load_subfolder/subfolder/00-base.xml deleted file mode 100644 index 27c7f0b7e..000000000 --- a/tests/dictionaries_old/00load_subfolder/subfolder/00-base.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/tests/dictionaries_old/00load_subfolder/tiramisu/base.py b/tests/dictionaries_old/00load_subfolder/tiramisu/base.py index 809b77b5c..f60bf8c84 100644 --- a/tests/dictionaries_old/00load_subfolder/tiramisu/base.py +++ b/tests/dictionaries_old/00load_subfolder/tiramisu/base.py @@ -1,18 +1,29 @@ -from importlib.machinery import SourceFileLoader -from importlib.util import spec_from_loader, module_from_spec -loader = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py') -spec = spec_from_loader(loader.name, loader) -func = module_from_spec(spec) -loader.exec_module(func) -for key, value in dict(locals()).items(): - if key != ['SourceFileLoader', 'func']: - setattr(func, key, value) +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries_old/../eosfunc/test.py') try: from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES except: from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) -option_4 = StrOption(name="mode_conteneur_actif1", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) -option_2 = OptionDescription(name="general", doc="général", children=[option_3, option_4], properties=frozenset({"normal"})) -option_1 = OptionDescription(name="rougail", doc="rougail", children=[option_2]) -option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[option_1]) +optiondescription_2 = OptionDescription(name="general", doc="général", children=[option_3], properties=frozenset({"normal"})) +optiondescription_1 = OptionDescription(name="rougail", doc="rougail", children=[optiondescription_2], properties=frozenset({"normal"})) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_1]) diff --git a/tests/dictionaries_old/00load_subfolder/tiramisu/multi.py b/tests/dictionaries_old/00load_subfolder/tiramisu/multi.py new file mode 100644 index 000000000..4aefc708f --- /dev/null +++ b/tests/dictionaries_old/00load_subfolder/tiramisu/multi.py @@ -0,0 +1,36 @@ +from importlib.machinery import SourceFileLoader as _SourceFileLoader +from importlib.util import spec_from_loader as _spec_from_loader, module_from_spec as _module_from_spec +class func: + pass + +def _load_functions(path): + global _SourceFileLoader, _spec_from_loader, _module_from_spec, func + loader = _SourceFileLoader('func', path) + spec = _spec_from_loader(loader.name, loader) + func_ = _module_from_spec(spec) + loader.exec_module(func_) + for function in dir(func_): + if function.startswith('_'): + continue + setattr(func, function, getattr(func_, function)) +_load_functions('tests/dictionaries/../eosfunc/test.py') +try: + from tiramisu4 import * + from tiramisu4.setting import ALLOWED_LEADER_PROPERTIES +except: + from tiramisu import * + from tiramisu.setting import ALLOWED_LEADER_PROPERTIES +ALLOWED_LEADER_PROPERTIES.add("basic") +ALLOWED_LEADER_PROPERTIES.add("normal") +ALLOWED_LEADER_PROPERTIES.add("expert") +option_2 = StrOption(name="mode_conteneur_actif1", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +option_3 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_1 = OptionDescription(name="general", doc="général", children=[option_2, option_3], properties=frozenset({"normal"})) +optiondescription_8 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_1], properties=frozenset({"normal"})) +optiondescription_7 = OptionDescription(name="1", doc="1", children=[optiondescription_8]) +option_5 = StrOption(name="mode_conteneur_actif1", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +option_6 = StrOption(name="mode_conteneur_actif", doc="No change", default="non", properties=frozenset({"force_default_on_freeze", "frozen", "hidden", "mandatory", "normal"})) +optiondescription_4 = OptionDescription(name="general", doc="général", children=[option_5, option_6], properties=frozenset({"normal"})) +optiondescription_10 = OptionDescription(name="rougail", doc="Rougail", children=[optiondescription_4], properties=frozenset({"normal"})) +optiondescription_9 = OptionDescription(name="2", doc="2", children=[optiondescription_10]) +option_0 = OptionDescription(name="baseoption", doc="baseoption", children=[optiondescription_7, optiondescription_9]) diff --git a/tests/dictionaries_old/00load_subfolder/99-base.xml b/tests/dictionaries_old/00load_subfolder/xml/99-base.xml similarity index 91% rename from tests/dictionaries_old/00load_subfolder/99-base.xml rename to tests/dictionaries_old/00load_subfolder/xml/99-base.xml index 849130906..f0576995a 100644 --- a/tests/dictionaries_old/00load_subfolder/99-base.xml +++ b/tests/dictionaries_old/00load_subfolder/xml/99-base.xml @@ -1,5 +1,5 @@ - +