Compare commits

...

26 Commits

Author SHA1 Message Date
ccc6924866 simplify objectspace 2020-12-23 17:36:50 +01:00
6c6746c58f help in variable or family now 2020-12-23 13:29:51 +01:00
08ed28fc95 remove_check and remove_condition must be explicite 2020-12-23 11:50:20 +01:00
afdc19887f simplify normalize_family 2020-12-23 11:28:43 +01:00
0e08757e22 test multiple xmlfiles in error 2020-12-22 21:11:14 +01:00
90bd72de69 remove condition not only a target 2020-12-22 20:19:01 +01:00
80b7f1b083 remove xml_compare 2020-12-22 17:25:13 +01:00
7d42517430 remove 'imp' warning 2020-12-22 17:22:56 +01:00
d18906e011 better debug 2020-11-21 08:11:34 +01:00
62bccfc352 set good path in include file and patch file 2020-11-20 18:02:40 +01:00
7db3e2c2a9 allow filename with \ 2020-11-18 22:18:16 +01:00
3ad1bf0604 valid_not_equal must be launch with 'todict' argument 2020-11-15 11:22:09 +01:00
d5129d6fe7 add float support 2020-11-15 11:02:04 +01:00
6bda645903 leadership name 2020-11-14 17:20:55 +01:00
a835e5a017 valid_in_network should works with CIDR 2020-11-14 08:02:38 +01:00
5a45885ed8 family and var with same name 2020-11-11 16:59:44 +01:00
3d49f2fe8c add xmlfiles in various error message 2020-11-11 16:24:06 +01:00
f7db6b0289 add remove_fill attribute 2020-11-08 09:51:33 +01:00
8f01d2c1d8 can add personal function (tests file) 2020-11-08 09:43:45 +01:00
4b21b1507f can add personal function 2020-10-14 18:17:31 +02:00
43e30bba47 support empty param 2020-10-04 20:11:00 +02:00
3040a11de9 cherry-pick 2020-10-04 17:34:48 +02:00
8cb27a79d6 doc 2020-10-04 17:28:07 +02:00
101dfefaa9 dynamic variable and calculation 2020-10-04 17:27:55 +02:00
5eba872969 add OptionInformation support 2020-10-04 17:25:42 +02:00
246ac25791 refactor valid_enum 2020-10-04 17:23:55 +02:00
468 changed files with 2418 additions and 2925 deletions

23
doc/auto.rst Normal file
View File

@ -0,0 +1,23 @@
Valeur automatiquement modifiée
===============================
Une variable avec valeur automatiquement modifiée est une variable dont la valeur sera considéré comme modifié quand le serveur sera déployé.
Voici un variable a valeur automatiquement modifiée :
<variable name="my_variable" type="oui/non" description="My variable" auto_save="True">
Dans ce cas la valeur est fixée à la valeur actuelle.
Par exemple, si la valeur de cette variable est issue d'un calcul, la valeur ne sera plus recalculée.
Valeur en lecture seule automatique
===================================
Une variable avec valeur en lecture seule automatique est une variable dont la valeur ne sera plus modifiable par l'utilisateur quand le serveur sera déployé.
Voici un variable à valeur en lecture seule automatique :
<variable name="my_variable" type="oui/non" description="My variable" auto_freeze="True">
Dans ce cas la valeur est fixée à la valeur actuelle et elle ne sera plus modifiable par l'utilisateur.
Par exemple, si la valeur de cette variable est issue d'un calcul, la valeur ne sera plus recalculée.

285
doc/fill.rst Normal file
View File

@ -0,0 +1,285 @@
Les variables calculées
=======================
Une variable calculée est une variable donc sa valeur est le résultat d'une fonction python.
Variable avec une valeur par défaut calculée
--------------------------------------------
Créons une variable de type "oui/non" donc la valeur est retournée par la fonction "return_no" :
<variables>
<family name="family">
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable"/>
</family>
</variables>
<constraints>
<fill name="return_no" target="my_calculated_variable"/>
</constraints>
Puis créons la fonction "return_no" :
def return_no():
return 'non'
Dans ce cas, la valeur par défaut est la valeur retournée par la fonction (ici "non"), elle sera calculée tant que l'utilisateur n'a pas de spécifié une valeur à cette variable.
Si l'utilisateur à définit une valeur par défaut à "my_calculated_variable" :
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable">
<value>oui</value>
</variable>
Cette valeur par défaut sera complètement ignorée.
Variable avec une valeur calculée
---------------------------------
En ajoutant le paramètre "hidden" à "True" dans la variable précédente, l'utilisateur n'aura plus la possibilité de modifié la valeur. La valeur de la variable sera donc systématiquement calculée :
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable" hidden="True"/>
Si une condition "hidden_if_in" est spécifié à la variable, la valeur sera modifiable par l'utilisateur si elle n'est pas cachée mais elle sera systèmatiquement calculée (même si elle a déjà était modifiée) si la variable est cachée.
Variable avec valeur calculée obligatoire
-----------------------------------------
Par défaut les variables calculées ne sont pas des varibles obligatoires.
Dans ce cas un calcul peut retourner None, mais surtout un utilisateur peut spécifier une valeur nulle à cette variable. Dans ce cas le calcul ne sera pas réalisé.
Fonction avec une valeur fixe comme paramètre positionnel
---------------------------------------------------------
Déclarons un calcul avec paramètre :
<constraints>
<fill name="return_value" target="my_calculated_variable">
<param>non</param>
</fill>
</constraints>
Créons la fonction correspondante :
def return_value(value):
return value
La variable aura donc "non" comme valeur puisque le paramètre aura la valeur fixe "non".
Paramètre nommée
----------------
Déclarons une contrainte avec un paramètre nommée :
<constraints>
<fill name="return_value" target="my_calculated_variable">
<param name="valeur">non</param>
</fill>
</constraints>
Dans ce cas la fonction return_value sera exécuté avec le paramètre nommé "valeur" dont sa valeur sera "non".
Paramètre avec un nombre
------------------------
Déclarons un calcul avec paramètre avec un nombre :
<constraints>
<fill name="return_value_with_number" target="my_calculated_variable">
<param type="number">1</param>
</fill>
</constraints>
Créons la fonction correspondante :
def return_value_with_number(value):
if value == 1:
return 'non'
return 'oui'
La variable aura donc "non" comme valeur puisque le paramètre aura la valeur fixe "1".
Paramètre dont la valeur est issue d'une autre variable
-------------------------------------------------------
Créons deux variables avec une contrainte de type variable qui contient le nom de la variable dont sa valeur sera utilisé comme paramètre :
<variables>
<family name="family">
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable"/>
<variable name="my_variable" type="number" description="My variable">
<value>1</value>
</variable>
</family>
</variables>
<constraints>
<fill name="return_value_with_number" target="my_calculated_variable">
<param type="variable">my_variable</param>
</fill>
</constraints>
Si l'utilisateur laisse la valeur 1 à "my_variable", la valeur par défault de la variable "my_calculated_variable" sera "non".
Si la valeur de "my_variable" est différent de 1, la valeur par défaut de la variable "my_calculated_variable" sera "oui".
Paramètre dont la valeur est issue d'une information de la configuration
------------------------------------------------------------------------
Créons une variable et la contrainte :
<variables>
<family name="family">
<variable name="my_calculated_variable" type="string" description="My calculated variable"/>
</family>
</variables>
<constraints>
<fill name="return_value" target="my_calculated_variable">
<param type="information">server_name</param>
</fill>
</constraints>
Dans ce cas, l'information de la configuration "server_name" sera utilisé comme valeur de la variable "my_calculated_variable".
Si l'information n'existe pas, la paramètre aura la valeur "None".
Paramètre avec variable potentiellement non existante
-----------------------------------------------------
Suivant le contexte une variable peut exister ou ne pas exister.
Un paramètre de type "variable" peut être "optional" :
<variables>
<family name="family">
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable"/>
</family>
</variables>
<constraints>
<fill name="return_value" target="my_calculated_variable">
<param type="variable" optional="True">unknow_variable</param>
</fill>
</constraints>
Dans ce cas la fonction "return_value" est exécuté sans paramètre.
Paramètre avec variable potentiellement désactivée
--------------------------------------------------
FIXME :
<!ATTLIST param notraisepropertyerror (True|False) "False">
Il n'y a pas spécialement de test !
Les variables suiveuses
-----------------------
FIXME :
- tests/flattener_dicos/10leadership_append/00-base.xml
- tests/flattener_dicos/10leadership_auto/00-base.xml
- tests/flattener_dicos/10leadership_autoleader/00-base.xml
- tests/flattener_dicos/10leadership_autoleader_expert/00-base.xml
Les variables dynamiques
------------------------
Paramètre avec variable dynamique
'''''''''''''''''''''''''''''''''
Il est possible de faire un calcul avec comme paramètre une variable dynamique mais pour une suffix particulier :
<variables>
<family name='family'>
<variable name='suffixes' type='string' description="Suffixes of dynamic family" multi="True">
<value>val1</value>
<value>val2</value>
</variable>
<variable name="my_calculated_variable" type="string" description="My calculated variable"/>
</family>
<family name='dyn' dynamic="suffixes">
<variable name='vardyn' type='string' description="Dynamic variable">
<value>val</value>
</variable>
</family>
</variables>
<constraints>
<fill name="return_value" target="my_calculated_variable">
<param type="variable">vardynval1</param>
</fill>
</constraints>
Dans ce cas, valeur du paramètre de la fonction "return_value" sera la valeur de la variable "vardyn" avec le suffix "val1".
Calcule d'une variable dynamique
''''''''''''''''''''''''''''''''
Il est également possible de calculer une variable dynamique à partir d'une variable standard :
<variables>
<family name='family'>
<variable name='suffixes' type='string' description="Suffixes of dynamic family" multi="True">
<value>val1</value>
<value>val2</value>
</variable>
<variable name="my_variable" type="string" description="My variable">
<value>val</value>
</variable>
</family>
<family name='dyn' dynamic="suffixes">
<variable name="my_calculated_variable_dyn_" type="string" description="My calculated variable"/>
<value>val</value>
</variable>
</family>
</variables>
<constraints>
<fill name="return_value" target="my_calculated_variable_dyn_">
<param type="variable">my_variable</param>
</fill>
</constraints>
Dans ce cas, les variables dynamiques "my_calculated_variable_dyn_" seront calculés à partir de la valeur de la variable "my_variable".
Que cela soit pour la variable "my_calculated_variable_dyn_val1" et "my_calculated_variable_dyn_val2".
Par contre, il n'est pas possible de faire un calcul pour une seule des deux variables issues de la variable dynamique.
Si c'est ce que vous cherchez à faire, il faudra prévoir un traitement particulier dans votre fonction.
Dans ce cas, il faut explicitement demander la valeur du suffix dans la fonction :
<constraints>
<fill name="return_value_suffix" target="my_calculated_variable_dyn_">
<param type="variable">my_variable</param>
<param type="suffix"/>
</fill>
</constraints>
Et ainsi faire un traitement spécifique pour ce suffix :
def return_value_suffix(value, suffix):
if suffix == 'val1':
return value
Redéfinition des calcules
-------------------------
Dans un premier dictionnaire déclarons notre variable et notre calcule :
<variables>
<family name="family">
<variable name="my_calculated_variable" type="oui/non" description="My calculated variable"/>
</family>
</variables>
<constraints>
<fill name="return_no" target="my_calculated_variable"/>
</constraints>
Dans un second dictionnaire il est possible de redéfinir le calcul :
<variables>
<family name="family">
<variable name="my_calculated_variable" redefine="True"/>
</family>
</variables>
<constraints>
<fill name="return_yes" target="my_calculated_variable"/>
</constraints>
Dans ce cas, à aucun moment la fonction "return_no" ne sera exécuté. Seul la fonction "return_yes" le sera.

13
doc/variable.rst Normal file
View File

@ -0,0 +1,13 @@
Variable
========
Variable obligatoire
--------------------
Variable dont une valeur est requise :
<variables>
<family name="family">
<variable name="my_variable" type="oui/non" description="My variable" mandatory="True"/>
</family>
</variables>

View File

@ -5,7 +5,7 @@ from typing import List
from collections import OrderedDict from collections import OrderedDict
from os.path import join, basename from os.path import join, basename
from ast import literal_eval from ast import literal_eval
import imp from importlib.machinery import SourceFileLoader
from .i18n import _ from .i18n import _
@ -34,11 +34,38 @@ def mode_factory():
modes = mode_factory() modes = mode_factory()
CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
'float': dict(opttype="FloatOption", func=float),
'choice': dict(opttype="ChoiceOption"),
'string': dict(opttype="StrOption"),
'password': dict(opttype="PasswordOption"),
'mail': dict(opttype="EmailOption"),
'boolean': dict(opttype="BoolOption"),
'symlink': dict(opttype="SymLinkOption"),
'filename': dict(opttype="FilenameOption"),
'date': dict(opttype="DateOption"),
'unix_user': dict(opttype="UsernameOption"),
'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}),
'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}),
'netmask': dict(opttype="NetmaskOption"),
'network': dict(opttype="NetworkOption"),
'broadcast': dict(opttype="BroadcastOption"),
'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}),
'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}),
'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}),
'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}),
'port': dict(opttype="PortOption", initkwargs={'allow_private': True}),
'mac': dict(opttype="MACOption"),
'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
}
# a CreoleObjSpace's attribute has some annotations # a CreoleObjSpace's attribute has some annotations
# that shall not be present in the exported (flatened) XML # that shall not be present in the exported (flatened) XML
ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace', ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check', 'namespace',
'remove_condition', 'path', 'instance_mode', 'index', 'is_in_leadership', 'remove_condition', 'path', 'instance_mode', 'index', 'is_in_leadership',
'level') # , '_real_container') 'level', 'remove_fill', 'xmlfiles')
ERASED_CONTAINER_ATTRIBUTES = ('id', 'container', 'group_id', 'group', 'container_group') ERASED_CONTAINER_ATTRIBUTES = ('id', 'container', 'group_id', 'group', 'container_group')
FORCE_CHOICE = {'oui/non': ['oui', 'non'], FORCE_CHOICE = {'oui/non': ['oui', 'non'],
@ -56,11 +83,6 @@ KEY_TYPE = {'variable': 'symlink',
'URLOption': 'web_address', 'URLOption': 'web_address',
'FilenameOption': 'filename'} 'FilenameOption': 'filename'}
TYPE_PARAM_CHECK = ('string', 'python', 'variable')
TYPE_PARAM_CONDITION = ('string', 'python', 'number', 'variable')
TYPE_PARAM_FILL = ('string', 'number', 'variable')
CONVERSION = {'number': int}
FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie' FREEZE_AUTOFREEZE_VARIABLE = 'module_instancie'
PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze', PROPERTIES = ('hidden', 'frozen', 'auto_freeze', 'auto_save', 'force_default_on_freeze',
@ -111,7 +133,7 @@ class GroupAnnotator:
self.manage_follower(namespace, self.manage_follower(namespace,
leader_family_name, leader_family_name,
variable, variable,
leader_name, leadership_name,
follower_names, follower_names,
leader_space, leader_space,
leader_is_hidden, leader_is_hidden,
@ -128,9 +150,14 @@ class GroupAnnotator:
# if variable.hidden: # if variable.hidden:
# leader_is_hidden = True # leader_is_hidden = True
else: else:
leader_space = self.objectspace.Leadership() leader_space = self.objectspace.Leadership(variable.xmlfiles)
if hasattr(group, 'name'):
leadership_name = group.name
else:
leadership_name = leader_name
leader_is_hidden = self.manage_leader(leader_space, leader_is_hidden = self.manage_leader(leader_space,
leader_family_name, leader_family_name,
leadership_name,
leader_name, leader_name,
namespace, namespace,
variable, variable,
@ -139,12 +166,13 @@ class GroupAnnotator:
) )
has_a_leader = True has_a_leader = True
else: else:
raise DictConsistencyError(_('cannot found followers {}').format(follower_names)) raise DictConsistencyError(_('cannot found followers "{}"').format('", "'.join(follower_names)))
del self.objectspace.space.constraints.group del self.objectspace.space.constraints.group
def manage_leader(self, def manage_leader(self,
leader_space: 'Leadership', leader_space: 'Leadership',
leader_family_name: str, leader_family_name: str,
leadership_name: str,
leader_name: str, leader_name: str,
namespace: str, namespace: str,
variable: 'Variable', variable: 'Variable',
@ -155,7 +183,7 @@ class GroupAnnotator:
if variable.multi is not True: if variable.multi is not True:
raise DictConsistencyError(_('the variable {} in a group must be multi').format(variable.name)) raise DictConsistencyError(_('the variable {} in a group must be multi').format(variable.name))
leader_space.variable = [] leader_space.variable = []
leader_space.name = leader_name leader_space.name = leadership_name
leader_space.hidden = variable.hidden leader_space.hidden = variable.hidden
if variable.hidden: if variable.hidden:
leader_is_hidden = True leader_is_hidden = True
@ -170,9 +198,9 @@ class GroupAnnotator:
leader_space.doc = variable.description leader_space.doc = variable.description
else: else:
leader_space.doc = variable.name leader_space.doc = variable.name
leader_path = namespace + '.' + leader_family_name + '.' + leader_name leadership_path = namespace + '.' + leader_family_name + '.' + leadership_name
self.objectspace.paths.add_family(namespace, self.objectspace.paths.add_family(namespace,
leader_path, leadership_path,
leader_space, leader_space,
) )
leader_family = self.objectspace.space.variables[namespace].family[leader_family_name] leader_family = self.objectspace.space.variables[namespace].family[leader_family_name]
@ -236,7 +264,7 @@ class ServiceAnnotator:
families = {} families = {}
for idx, service_name in enumerate(self.objectspace.space.services.service.keys()): for idx, service_name in enumerate(self.objectspace.space.services.service.keys()):
service = self.objectspace.space.services.service[service_name] service = self.objectspace.space.services.service[service_name]
new_service = self.objectspace.service() new_service = self.objectspace.service(service.xmlfiles)
for elttype, values in vars(service).items(): for elttype, values in vars(service).items():
if not isinstance(values, (dict, list)) or elttype in ERASED_ATTRIBUTES: if not isinstance(values, (dict, list)) or elttype in ERASED_ATTRIBUTES:
setattr(new_service, elttype, values) setattr(new_service, elttype, values)
@ -245,6 +273,7 @@ class ServiceAnnotator:
path = '.'.join(['services', service_name, eltname]) path = '.'.join(['services', service_name, eltname])
family = self.gen_family(eltname, family = self.gen_family(eltname,
path, path,
service.xmlfiles,
) )
if isinstance(values, dict): if isinstance(values, dict):
values = list(values.values()) values = list(values.values())
@ -261,8 +290,9 @@ class ServiceAnnotator:
def gen_family(self, def gen_family(self,
name, name,
path, path,
xmlfiles
): ):
family = self.objectspace.family() family = self.objectspace.family(xmlfiles)
family.name = normalize_family(name) family.name = normalize_family(name)
family.doc = name family.doc = name
family.mode = None family.mode = None
@ -310,7 +340,10 @@ class ServiceAnnotator:
if not self.objectspace.paths.family_is_defined(subpath): if not self.objectspace.paths.family_is_defined(subpath):
break break
idx += 1 idx += 1
family = self.gen_family(c_name, subpath) family = self.gen_family(c_name,
subpath,
elt.xmlfiles,
)
family.variable = [] family.variable = []
listname = '{}list'.format(name) listname = '{}list'.format(name)
activate_path = '.'.join([subpath, 'activate']) activate_path = '.'.join([subpath, 'activate'])
@ -348,7 +381,7 @@ class ServiceAnnotator:
elt, elt,
path, path,
): ):
variable = self.objectspace.variable() variable = self.objectspace.variable(elt.xmlfiles)
variable.name = normalize_family(key) variable.name = normalize_family(key)
variable.mode = None variable.mode = None
if key == 'name': if key == 'name':
@ -373,7 +406,7 @@ class ServiceAnnotator:
variable.multi = None variable.multi = None
else: else:
variable.doc = key variable.doc = key
val = self.objectspace.value() val = self.objectspace.value(elt.xmlfiles)
val.type = type_ val.type = type_
val.name = value val.name = value
variable.value = [val] variable.value = [val]
@ -431,8 +464,7 @@ class ServiceAnnotator:
if not hasattr(file_, 'source'): if not hasattr(file_, 'source'):
file_.source = basename(file_.name) file_.source = basename(file_.name)
elif not hasattr(file_, 'source'): elif not hasattr(file_, 'source'):
raise DictConsistencyError(_('attribute source mandatory for file with variable name ' raise DictConsistencyError(_('attribute source mandatory for file with variable name for {}').format(file_.name))
'for {}').format(file_.name))
class VariableAnnotator: class VariableAnnotator:
@ -441,7 +473,6 @@ class VariableAnnotator:
): ):
self.objectspace = objectspace self.objectspace = objectspace
self.convert_variable() self.convert_variable()
self.convert_helps()
self.convert_auto_freeze() self.convert_auto_freeze()
self.convert_separators() self.convert_separators()
@ -457,7 +488,7 @@ class VariableAnnotator:
for value in variable.value: for value in variable.value:
if not hasattr(value, 'type'): if not hasattr(value, 'type'):
value.type = variable.type value.type = variable.type
value.name = CONVERSION.get(value.type, str)(value.name) value.name = CONVERT_OPTION.get(value.type, {}).get('func', str)(value.name)
for key, value in RENAME_ATTIBUTES.items(): for key, value in RENAME_ATTIBUTES.items():
setattr(variable, value, getattr(variable, key)) setattr(variable, value, getattr(variable, key))
setattr(variable, key, None) setattr(variable, key, None)
@ -472,21 +503,28 @@ class VariableAnnotator:
path, path,
): ):
if variable.type in FORCE_CHOICE: if variable.type in FORCE_CHOICE:
check = self.objectspace.check() check = self.objectspace.check(variable.xmlfiles)
check.name = 'valid_enum' check.name = 'valid_enum'
check.target = path check.target = path
check.namespace = namespace check.namespace = namespace
param = self.objectspace.param() check.param = []
param.text = str(FORCE_CHOICE[variable.type]) for value in FORCE_CHOICE[variable.type]:
check.param = [param] param = self.objectspace.param(variable.xmlfiles)
param.text = value
check.param.append(param)
if not hasattr(self.objectspace.space, 'constraints'): if not hasattr(self.objectspace.space, 'constraints'):
self.objectspace.space.constraints = self.objectspace.constraints() self.objectspace.space.constraints = self.objectspace.constraints(variable.xmlfiles)
self.objectspace.space.constraints.namespace = namespace self.objectspace.space.constraints.namespace = namespace
if not hasattr(self.objectspace.space.constraints, 'check'): if not hasattr(self.objectspace.space.constraints, 'check'):
self.objectspace.space.constraints.check = [] self.objectspace.space.constraints.check = []
self.objectspace.space.constraints.check.append(check) self.objectspace.space.constraints.check.append(check)
variable.type = 'string' variable.type = 'string'
def _valid_type(variable):
if variable.type not in CONVERT_OPTION:
xmlfiles = self.objectspace.display_xmlfiles(variable.xmlfiles)
raise DictConsistencyError(_(f'unvalid type "{variable.type}" for variable "{variable.name}" in {xmlfiles}'))
if not hasattr(self.objectspace.space, 'variables'): if not hasattr(self.objectspace.space, 'variables'):
return return
for families in self.objectspace.space.variables.values(): for families in self.objectspace.space.variables.values():
@ -516,6 +554,7 @@ class VariableAnnotator:
follower, follower,
path, path,
) )
_valid_type(follower)
else: else:
path = '{}.{}.{}'.format(namespace, normalize_family(family.name), variable.name) path = '{}.{}.{}'.format(namespace, normalize_family(family.name), variable.name)
_convert_variable(variable, _convert_variable(variable,
@ -525,32 +564,19 @@ class VariableAnnotator:
variable, variable,
path, path,
) )
_valid_type(variable)
def convert_helps(self):
if not hasattr(self.objectspace.space, 'help'):
return
helps = self.objectspace.space.help
if hasattr(helps, 'variable'):
for hlp in helps.variable.values():
variable = self.objectspace.paths.get_variable_obj(hlp.name)
variable.help = hlp.text
if hasattr(helps, 'family'):
for hlp in helps.family.values():
variable = self.objectspace.paths.get_family_obj(hlp.name)
variable.help = hlp.text
del self.objectspace.space.help
def convert_auto_freeze(self): # pylint: disable=C0111 def convert_auto_freeze(self): # pylint: disable=C0111
def _convert_auto_freeze(variable, namespace): def _convert_auto_freeze(variable, namespace):
if variable.auto_freeze: if variable.auto_freeze:
new_condition = self.objectspace.condition() new_condition = self.objectspace.condition(variable.xmlfiles)
new_condition.name = 'auto_hidden_if_not_in' new_condition.name = 'auto_hidden_if_not_in'
new_condition.namespace = namespace new_condition.namespace = namespace
new_condition.source = FREEZE_AUTOFREEZE_VARIABLE new_condition.source = FREEZE_AUTOFREEZE_VARIABLE
new_param = self.objectspace.param() new_param = self.objectspace.param(variable.xmlfiles)
new_param.text = 'oui' new_param.text = 'oui'
new_condition.param = [new_param] new_condition.param = [new_param]
new_target = self.objectspace.target() new_target = self.objectspace.target(variable.xmlfiles)
new_target.type = 'variable' new_target.type = 'variable'
path = variable.namespace + '.' + normalize_family(family.name) + '.' + variable.name path = variable.namespace + '.' + normalize_family(family.name) + '.' + variable.name
new_target.name = path new_target.name = path
@ -584,7 +610,8 @@ class VariableAnnotator:
subpath = self.objectspace.paths.get_variable_path(separator.name, subpath = self.objectspace.paths.get_variable_path(separator.name,
separator.namespace, separator.namespace,
) )
raise DictConsistencyError(_('{} already has a separator').format(subpath)) xmlfiles = self.objectspace.display_xmlfiles(separator.xmlfiles)
raise DictConsistencyError(_(f'{subpath} already has a separator in {xmlfiles}'))
option.separator = separator.text option.separator = separator.text
del family.separators del family.separators
@ -597,7 +624,9 @@ class ConstraintAnnotator:
if not hasattr(objectspace.space, 'constraints'): if not hasattr(objectspace.space, 'constraints'):
return return
self.objectspace = objectspace self.objectspace = objectspace
self.eosfunc = imp.load_source('eosfunc', eosfunc_file) eosfunc = SourceFileLoader('eosfunc', eosfunc_file).load_module()
self.functions = dir(eosfunc)
self.functions.extend(INTERNAL_FUNCTIONS)
self.valid_enums = {} self.valid_enums = {}
if hasattr(self.objectspace.space.constraints, 'check'): if hasattr(self.objectspace.space.constraints, 'check'):
self.check_check() self.check_check()
@ -619,21 +648,19 @@ class ConstraintAnnotator:
def check_check(self): def check_check(self):
remove_indexes = [] remove_indexes = []
functions = dir(self.eosfunc)
functions.extend(INTERNAL_FUNCTIONS)
for check_idx, check in enumerate(self.objectspace.space.constraints.check): for check_idx, check in enumerate(self.objectspace.space.constraints.check):
if not check.name in functions: if not check.name in self.functions:
raise DictConsistencyError(_('cannot find check function {}').format(check.name)) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'cannot find check function "{check.name}" in {xmlfiles}'))
if hasattr(check, 'param'): if hasattr(check, 'param'):
param_option_indexes = [] param_option_indexes = []
for idx, param in enumerate(check.param): for idx, param in enumerate(check.param):
if param.type not in TYPE_PARAM_CHECK:
raise DictConsistencyError(_('cannot use {} type as a param in check for {}').format(param.type, check.target))
if param.type == 'variable' and not self.objectspace.paths.path_is_defined(param.text): if param.type == 'variable' and not self.objectspace.paths.path_is_defined(param.text):
if param.optional is True: if param.optional is True:
param_option_indexes.append(idx) param_option_indexes.append(idx)
else: else:
raise DictConsistencyError(_(f'unknown param {param.text} in check')) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'cannot find check param "{param.text}" in {xmlfiles}'))
if param.type != 'variable': if param.type != 'variable':
param.notraisepropertyerror = None param.notraisepropertyerror = None
param_option_indexes = list(set(param_option_indexes)) param_option_indexes = list(set(param_option_indexes))
@ -661,55 +688,53 @@ class ConstraintAnnotator:
remove_indexes = [] remove_indexes = []
for idx, check in enumerate(self.objectspace.space.constraints.check): for idx, check in enumerate(self.objectspace.space.constraints.check):
if check.name == 'valid_enum': if check.name == 'valid_enum':
if len(check.param) != 1:
raise DictConsistencyError(_(f'cannot set more than one param for valid_enum for variable {check.target}'))
param = check.param[0]
if check.target in self.valid_enums: if check.target in self.valid_enums:
raise DictConsistencyError(_(f'valid_enum already set for {check.target}')) old_xmlfiles = self.objectspace.display_xmlfiles(self.valid_enums[check.target]['xmlfiles'])
if param.type not in ['string', 'python', 'number']: xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'unknown type {param.type} for param in valid_enum for {check.target}')) raise DictConsistencyError(_(f'valid_enum define in {xmlfiles} but already set in {old_xmlfiles} for "{check.target}", did you forget remove_check?'))
if not hasattr(check, 'param'):
raise DictConsistencyError(_(f'param is mandatory for a valid_enum of variable {check.target}'))
variable = self.objectspace.paths.get_variable_obj(check.target) variable = self.objectspace.paths.get_variable_obj(check.target)
values = self.load_params_in_validenum(param, values = self.load_params_in_valid_enum(check.param,
variable.name, variable.name,
variable.type, variable.type,
) )
self.valid_enums[check.target] = {'type': param.type,
'values': values}
self._set_valid_enum(variable, self._set_valid_enum(variable,
values, values,
variable.type, variable.type,
check.target,
check.xmlfiles,
) )
remove_indexes.append(idx) remove_indexes.append(idx)
remove_indexes.sort(reverse=True) remove_indexes.sort(reverse=True)
for idx in remove_indexes: for idx in remove_indexes:
del self.objectspace.space.constraints.check[idx] del self.objectspace.space.constraints.check[idx]
def load_params_in_validenum(self, def load_params_in_valid_enum(self,
param, params,
variable_name, variable_name,
variable_type, variable_type,
): ):
if not hasattr(param, 'text') and (param.type == 'python' or param.type == 'number'): has_variable = None
raise DictConsistencyError(_(f"All '{param.type}' variables shall be set in order to calculate valid_enum for variable {variable_name}")) values = []
if variable_type == 'string' and param.type == 'number': for param in params:
raise DictConsistencyError(_(f'Unconsistency valid_enum type ({param.type}), for variable {variable_name}')) if param.type == 'variable':
if param.type == 'python': if has_variable is not None:
try: raise DictConsistencyError(_(f'only one "variable" parameter is allowed for valid_enum of variable {variable_name}'))
values = eval(param.text, {'eosfunc': self.eosfunc, '__builtins__': {'range': range, 'str': str}}) has_variable = True
except NameError: variable = self.objectspace.paths.get_variable_obj(param.text)
raise DictConsistencyError(_('The function {} is unknown').format(param.text)) if not variable.multi:
else: raise DictConsistencyError(_(f'only multi "variable" parameter is allowed for valid_enum of variable {variable_name}'))
try: values = param.text
values = literal_eval(param.text) else:
except ValueError: if has_variable:
raise DictConsistencyError(_(f'Cannot load {param.text} in valid_enum')) raise DictConsistencyError(_(f'only one "variable" parameter is allowed for valid_enum of variable {variable_name}'))
if not isinstance(values, list): if not hasattr(param, 'text'):
raise DictConsistencyError(_('Function {} shall return a list').format(param.text)) if param.type == 'number':
for value in values: raise DictConsistencyError(_(f'value is mandatory for valid_enum of variable {variable_name}'))
if variable_type == 'string' and not isinstance(value, str): values.append(None)
raise DictConsistencyError(_(f'Cannot load "{param.text}", "{value}" is not a string')) else:
if variable_type == 'number' and not isinstance(value, int): values.append(param.text)
raise DictConsistencyError(_(f'Cannot load "{param.text}", "{value}" is not a number'))
return values return values
def check_change_warning(self): def check_change_warning(self):
@ -727,6 +752,7 @@ class ConstraintAnnotator:
if target.type == 'variable': if target.type == 'variable':
variable = self.objectspace.paths.get_variable_obj(target.name) variable = self.objectspace.paths.get_variable_obj(target.name)
family = self.objectspace.paths.get_family_obj(target.name.rsplit('.', 1)[0]) family = self.objectspace.paths.get_family_obj(target.name.rsplit('.', 1)[0])
# it's a leader, so apply property to leadership
if isinstance(family, self.objectspace.Leadership) and family.name == variable.name: if isinstance(family, self.objectspace.Leadership) and family.name == variable.name:
return family, family.variable return family, family.variable
return variable, [variable] return variable, [variable]
@ -736,9 +762,6 @@ class ConstraintAnnotator:
def check_params_target(self): def check_params_target(self):
for condition in self.objectspace.space.constraints.condition: for condition in self.objectspace.space.constraints.condition:
for param in condition.param:
if param.type not in TYPE_PARAM_CONDITION:
raise DictConsistencyError(_(f'cannot use {param.type} type as a param in a condition'))
if not hasattr(condition, 'target'): if not hasattr(condition, 'target'):
raise DictConsistencyError(_('target is mandatory in condition')) raise DictConsistencyError(_('target is mandatory in condition'))
for target in condition.target: for target in condition.target:
@ -753,13 +776,15 @@ class ConstraintAnnotator:
if condition.source == target.name: if condition.source == target.name:
raise DictConsistencyError(_('target name and source name must be different: {}').format(condition.source)) raise DictConsistencyError(_('target name and source name must be different: {}').format(condition.source))
try: try:
target.name = self.objectspace.paths.get_variable_path(target.name, namespace) target_names = [normalize_family(name) for name in target.name.split('.')]
target.name = self.objectspace.paths.get_variable_path('.'.join(target_names), namespace)
except DictConsistencyError: except DictConsistencyError:
# for optional variable # for optional variable
pass pass
elif target.type == 'family': elif target.type == 'family':
try: try:
target.name = self.objectspace.paths.get_family_path(target.name, namespace) target_names = [normalize_family(name) for name in target.name.split('.')]
target.name = self.objectspace.paths.get_family_path('.'.join(target_names), namespace)
except KeyError: except KeyError:
raise DictConsistencyError(_('cannot found family {}').format(target.name)) raise DictConsistencyError(_('cannot found family {}').format(target.name))
@ -777,7 +802,7 @@ class ConstraintAnnotator:
for listvar in listvars: for listvar in listvars:
variable = self.objectspace.paths.get_variable_obj(listvar) variable = self.objectspace.paths.get_variable_obj(listvar)
type_ = 'variable' type_ = 'variable'
new_target = self.objectspace.target() new_target = self.objectspace.target(variable.xmlfiles)
new_target.type = type_ new_target.type = type_
new_target.name = listvar new_target.name = listvar
new_target.index = target.index new_target.index = target.index
@ -892,67 +917,87 @@ class ConstraintAnnotator:
inverse = condition.name.endswith('_if_not_in') inverse = condition.name.endswith('_if_not_in')
actions = self._get_condition_actions(condition.name) actions = self._get_condition_actions(condition.name)
for param in condition.param: for param in condition.param:
if hasattr(param, 'text'): text = getattr(param, 'text', None)
param = param.text
else:
param = None
for target in condition.target: for target in condition.target:
leader_or_variable, variables = self._get_family_variables_from_target(target) leader_or_variable, variables = self._get_family_variables_from_target(target)
# if option is already disable, do not apply disable_if_in # if option is already disable, do not apply disable_if_in
if hasattr(leader_or_variable, actions[0]) and getattr(leader_or_variable, actions[0]) is True: # check only the first action (example of multiple actions: 'hidden', 'frozen', 'force_default_on_freeze')
main_action = actions[0]
if getattr(leader_or_variable, main_action, False) is True:
continue continue
for idx, action in enumerate(actions): for idx, action in enumerate(actions):
prop = self.objectspace.property_() prop = self.objectspace.property_(leader_or_variable.xmlfiles)
prop.type = 'calculation' prop.type = 'calculation'
prop.inverse = inverse prop.inverse = inverse
prop.source = condition.source prop.source = condition.source
prop.expected = param prop.expected = text
prop.name = action prop.name = action
if idx == 0: if idx == 0:
# main action is for the variable or family
if not hasattr(leader_or_variable, 'property'): if not hasattr(leader_or_variable, 'property'):
leader_or_variable.property = [] leader_or_variable.property = []
leader_or_variable.property.append(prop) leader_or_variable.property.append(prop)
else: else:
# other actions are set to the variable or children of family
for variable in variables: for variable in variables:
if not hasattr(variable, 'property'): if not hasattr(variable, 'property'):
variable.property = [] variable.property = []
variable.property.append(prop) variable.property.append(prop)
del self.objectspace.space.constraints.condition del self.objectspace.space.constraints.condition
def _set_valid_enum(self, variable, values, type_): def _set_valid_enum(self,
variable,
values,
type_,
target: str,
xmlfiles: List[str],
):
# value for choice's variable is mandatory # value for choice's variable is mandatory
variable.mandatory = True variable.mandatory = True
# build choice # build choice
variable.choice = [] variable.choice = []
choices = [] if isinstance(values, str):
for value in values:
choice = self.objectspace.choice() choice = self.objectspace.choice()
try: choice.type = 'calculation'
choice.name = CONVERSION.get(type_, str)(value) choice.name = values
except:
raise DictConsistencyError(_(f'unable to change type of a valid_enum entry "{value}" is not a valid "{type_}" for "{variable.name}"'))
if choice.name == '':
choice.name = None
choices.append(choice.name)
choice.type = type_
variable.choice.append(choice) variable.choice.append(choice)
else:
self.valid_enums[target] = {'type': type_,
'values': values,
'xmlfiles': xmlfiles,
}
choices = []
for value in values:
choice = self.objectspace.choice(variable.xmlfiles)
try:
if value is not None:
choice.name = CONVERT_OPTION[type_].get('func', str)(value)
else:
choice.name = value
except:
raise DictConsistencyError(_(f'unable to change type of a valid_enum entry "{value}" is not a valid "{type_}" for "{variable.name}"'))
if choice.name == '':
choice.name = None
choices.append(choice.name)
choice.type = type_
variable.choice.append(choice)
# check value or set first choice value has default value
if hasattr(variable, 'value'):
for value in variable.value:
value.type = type_
try:
cvalue = CONVERT_OPTION[type_].get('func', str)(value.name)
except:
raise DictConsistencyError(_(f'unable to change type of value "{value}" is not a valid "{type_}" for "{variable.name}"'))
if cvalue not in choices:
raise DictConsistencyError(_('value "{}" of variable "{}" is not in list of all expected values ({})').format(value.name, variable.name, choices))
else:
new_value = self.objectspace.value(variable.xmlfiles)
new_value.name = choices[0]
new_value.type = type_
variable.value = [new_value]
if not variable.choice: if not variable.choice:
raise DictConsistencyError(_('empty valid enum is not allowed for variable {}').format(variable.name)) raise DictConsistencyError(_('empty valid enum is not allowed for variable {}').format(variable.name))
# check value or set first choice value has default value
if hasattr(variable, 'value'):
for value in variable.value:
value.type = type_
try:
cvalue = CONVERSION.get(type_, str)(value.name)
except:
raise DictConsistencyError(_(f'unable to change type of value "{value}" is not a valid "{type_}" for "{variable.name}"'))
if cvalue not in choices:
raise DictConsistencyError(_('value "{}" of variable "{}" is not in list of all expected values ({})').format(value.name, variable.name, choices))
else:
new_value = self.objectspace.value()
new_value.name = values[0]
new_value.type = type_
variable.value = [new_value]
variable.type = 'choice' variable.type = 'choice'
def convert_check(self): def convert_check(self):
@ -972,26 +1017,30 @@ class ConstraintAnnotator:
else: else:
raise DictConsistencyError(_(f'unknown parameter {param.text} in check "valid_entier" for variable {check.target}')) raise DictConsistencyError(_(f'unknown parameter {param.text} in check "valid_entier" for variable {check.target}'))
else: else:
check_ = self.objectspace.check() check_ = self.objectspace.check(variable.xmlfiles)
if name == 'valid_differ': if name == 'valid_differ':
name = 'valid_not_equal' name = 'valid_not_equal'
elif name == 'valid_network_netmask': elif name == 'valid_network_netmask':
params_len = 1 params_len = 1
if len(check.param) != params_len: if len(check.param) != params_len:
raise DictConsistencyError(_('{} must have {} param').format(name, params_len)) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
elif name == 'valid_ipnetmask': elif name == 'valid_ipnetmask':
params_len = 1 params_len = 1
if len(check.param) != params_len: if len(check.param) != params_len:
raise DictConsistencyError(_('{} must have {} param').format(name, params_len)) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
name = 'valid_ip_netmask' name = 'valid_ip_netmask'
elif name == 'valid_broadcast': elif name == 'valid_broadcast':
params_len = 2 params_len = 2
if len(check.param) != params_len: if len(check.param) != params_len:
raise DictConsistencyError(_('{} must have {} param').format(name, params_len)) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
elif name == 'valid_in_network': elif name == 'valid_in_network':
params_len = 2 if len(check.param) not in (1, 2):
if len(check.param) != params_len: params_len = 2
raise DictConsistencyError(_('{} must have {} param').format(name, params_len)) xmlfiles = self.objectspace.display_xmlfiles(check.xmlfiles)
raise DictConsistencyError(_(f'{name} must have {params_len} param in {xmlfiles}'))
check_.name = name check_.name = name
check_.warnings_only = check.warnings_only check_.warnings_only = check.warnings_only
if hasattr(check, 'param'): if hasattr(check, 'param'):
@ -1007,33 +1056,39 @@ class ConstraintAnnotator:
indexes = list(fills.keys()) indexes = list(fills.keys())
indexes.sort() indexes.sort()
targets = [] targets = []
eosfunc = dir(self.eosfunc)
for idx in indexes: for idx in indexes:
fill = fills[idx] fill = fills[idx]
# test if it's redefined calculation # test if it's redefined calculation
if fill.target in targets and not fill.redefine: if fill.target in targets:
raise DictConsistencyError(_(f"A fill already exists for the target: {fill.target}")) xmlfiles = self.objectspace.display_xmlfiles(fill.xmlfiles)
raise DictConsistencyError(_(f'A fill already exists for the target of "{fill.target}" created in {xmlfiles}'))
targets.append(fill.target) targets.append(fill.target)
# #
if fill.name not in eosfunc: if fill.name not in self.functions:
raise DictConsistencyError(_('cannot find fill function {}').format(fill.name)) raise DictConsistencyError(_('cannot find fill function {}').format(fill.name))
namespace = fill.namespace namespace = fill.namespace
# let's replace the target by the path # let's replace the target by the path
fill.target = self.objectspace.paths.get_variable_path(fill.target, fill.target, suffix = self.objectspace.paths.get_variable_path(fill.target,
namespace, namespace,
) with_suffix=True,
)
value = self.objectspace.value() if suffix is not None:
raise DictConsistencyError(_(f'Cannot add fill function to "{fill.target}" only with the suffix "{suffix}"'))
variable = self.objectspace.paths.get_variable_obj(fill.target)
value = self.objectspace.value(variable.xmlfiles)
value.type = 'calculation' value.type = 'calculation'
value.name = fill.name value.name = fill.name
if hasattr(fill, 'param'): if hasattr(fill, 'param'):
param_to_delete = [] param_to_delete = []
for fill_idx, param in enumerate(fill.param): for fill_idx, param in enumerate(fill.param):
if param.type not in TYPE_PARAM_FILL: if param.type not in ['suffix', 'string'] and not hasattr(param, 'text'):
raise DictConsistencyError(_(f'cannot use {param.type} type as a param in a fill/auto')) raise DictConsistencyError(_(f"All '{param.type}' variables must have a value in order to calculate {fill.target}"))
if param.type != 'string' and not hasattr(param, 'text'): if param.type == 'suffix' and hasattr(param, 'text'):
raise DictConsistencyError(_(f"All '{param.type}' variables shall have a value in order to calculate {fill.target}")) raise DictConsistencyError(_(f"All '{param.type}' variables must not have a value in order to calculate {fill.target}"))
if param.type == 'string':
if not hasattr(param, 'text'):
param.text = None
if param.type == 'variable': if param.type == 'variable':
try: try:
param.text, suffix = self.objectspace.paths.get_variable_path(param.text, param.text, suffix = self.objectspace.paths.get_variable_path(param.text,
@ -1053,7 +1108,6 @@ class ConstraintAnnotator:
for param_idx in param_to_delete: for param_idx in param_to_delete:
fill.param.pop(param_idx) fill.param.pop(param_idx)
value.param = fill.param value.param = fill.param
variable = self.objectspace.paths.get_variable_obj(fill.target)
variable.value = [value] variable.value = [value]
del self.objectspace.space.constraints.fill del self.objectspace.space.constraints.fill
@ -1061,6 +1115,7 @@ class ConstraintAnnotator:
if hasattr(self.objectspace.space.constraints, 'index'): if hasattr(self.objectspace.space.constraints, 'index'):
del self.objectspace.space.constraints.index del self.objectspace.space.constraints.index
del self.objectspace.space.constraints.namespace del self.objectspace.space.constraints.namespace
del self.objectspace.space.constraints.xmlfiles
if vars(self.objectspace.space.constraints): if vars(self.objectspace.space.constraints):
raise Exception('constraints again?') raise Exception('constraints again?')
del self.objectspace.space.constraints del self.objectspace.space.constraints
@ -1121,7 +1176,7 @@ class FamilyAnnotator:
# if the variable is mandatory and doesn't have any value # if the variable is mandatory and doesn't have any value
# then the variable's mode is set to 'basic' # then the variable's mode is set to 'basic'
if not hasattr(variable, 'value') and variable.type == 'boolean': if not hasattr(variable, 'value') and variable.type == 'boolean':
new_value = self.objectspace.value() new_value = self.objectspace.value(variable.xmlfiles)
new_value.name = True new_value.name = True
new_value.type = 'boolean' new_value.type = 'boolean'
variable.value = [new_value] variable.value = [new_value]
@ -1136,9 +1191,9 @@ class FamilyAnnotator:
if param.type == 'variable': if param.type == 'variable':
has_variable = True has_variable = True
break break
if not has_variable: #if not has_variable:
# if one parameter is a variable, let variable choice if it's mandatory # # if one parameter is a variable, let variable choice if it's mandatory
variable.mandatory = True # variable.mandatory = True
if has_value: if has_value:
# if has value but without any calculation # if has value but without any calculation
variable.mandatory = True variable.mandatory = True

View File

@ -45,26 +45,26 @@
<!ELEMENT services (service*)> <!ELEMENT services (service*)>
<!ELEMENT service ((port* | tcpwrapper* | ip* | interface* | package* | file* | digitalcertificate* | override*)*) > <!ELEMENT service ((port* | tcpwrapper* | ip* | interface* | package* | file* | override*)*) >
<!ATTLIST service name CDATA #REQUIRED> <!ATTLIST service name CDATA #REQUIRED>
<!ATTLIST service manage (True|False) "True"> <!ATTLIST service manage (True|False) "True">
<!ELEMENT port (#PCDATA)> <!ELEMENT port (#PCDATA)>
<!ATTLIST port port_type (PortOption|SymLinkOption|variable) "PortOption"> <!ATTLIST port port_type (PortOption|variable) "PortOption">
<!ATTLIST port portlist CDATA #IMPLIED > <!ATTLIST port portlist CDATA #IMPLIED >
<!ATTLIST port protocol (tcp|udp) "tcp"> <!ATTLIST port protocol (tcp|udp) "tcp">
<!ELEMENT ip (#PCDATA)> <!ELEMENT ip (#PCDATA)>
<!ATTLIST ip iplist CDATA #IMPLIED > <!ATTLIST ip iplist CDATA #IMPLIED >
<!ATTLIST ip ip_type (NetworkOption|SymLinkOption|variable) "NetworkOption"> <!ATTLIST ip ip_type (NetworkOption|variable) "NetworkOption">
<!ATTLIST ip interface_type (UnicodeOption|SymLinkOption|variable) "UnicodeOption"> <!ATTLIST ip interface_type (UnicodeOption|variable) "UnicodeOption">
<!ATTLIST ip interface CDATA #REQUIRED> <!ATTLIST ip interface CDATA #REQUIRED>
<!ATTLIST ip netmask_type (NetmaskOption|SymLinkOption|variable) "NetmaskOption"> <!ATTLIST ip netmask_type (NetmaskOption|variable) "NetmaskOption">
<!ATTLIST ip netmask CDATA "255.255.255.255"> <!ATTLIST ip netmask CDATA "255.255.255.255">
<!ELEMENT file EMPTY> <!ELEMENT file EMPTY>
<!ATTLIST file name CDATA #REQUIRED > <!ATTLIST file name CDATA #REQUIRED >
<!ATTLIST file file_type (UnicodeOption|SymLinkOption|variable) "UnicodeOption"> <!ATTLIST file file_type (UnicodeOption|variable) "UnicodeOption">
<!ATTLIST file variable CDATA #IMPLIED> <!ATTLIST file variable CDATA #IMPLIED>
<!ATTLIST file variable_type (variable) "variable"> <!ATTLIST file variable_type (variable) "variable">
<!ATTLIST file source CDATA #IMPLIED> <!ATTLIST file source CDATA #IMPLIED>
@ -75,30 +75,24 @@
<!ATTLIST file redefine (True|False) "False"> <!ATTLIST file redefine (True|False) "False">
<!ATTLIST file templating (True|False) "True"> <!ATTLIST file templating (True|False) "True">
<!ELEMENT digitalcertificate EMPTY>
<!ATTLIST digitalcertificate name CDATA #REQUIRED >
<!ATTLIST digitalcertificate digitalcertificate_type (variable) "variable">
<!ATTLIST digitalcertificate certificate CDATA #REQUIRED >
<!ATTLIST digitalcertificate certificate_type (variable) "variable">
<!ATTLIST digitalcertificate type CDATA #REQUIRED >
<!ATTLIST digitalcertificate ca CDATA #REQUIRED >
<!ELEMENT override EMPTY> <!ELEMENT override EMPTY>
<!ATTLIST override source CDATA #IMPLIED > <!ATTLIST override source CDATA #IMPLIED >
<!ATTLIST override templating (True|False) "True"> <!ATTLIST override templating (True|False) "True">
<!ELEMENT variables (family*, separators*)> <!ELEMENT variables (family*, separators*)>
<!ELEMENT family (#PCDATA | variable)*> <!ELEMENT family (variable*)>
<!ATTLIST family name CDATA #REQUIRED> <!ATTLIST family name CDATA #REQUIRED>
<!ATTLIST family description CDATA #IMPLIED> <!ATTLIST family description CDATA #IMPLIED>
<!ATTLIST family help CDATA #IMPLIED>
<!ATTLIST family mode (basic|normal|expert) "basic"> <!ATTLIST family mode (basic|normal|expert) "basic">
<!ATTLIST family hidden (True|False) "False"> <!ATTLIST family hidden (True|False) "False">
<!ATTLIST family dynamic CDATA #IMPLIED> <!ATTLIST family dynamic CDATA #IMPLIED>
<!ELEMENT variable (#PCDATA | value)*> <!ELEMENT variable (value*)>
<!ATTLIST variable name CDATA #REQUIRED> <!ATTLIST variable name CDATA #REQUIRED>
<!ATTLIST variable type CDATA #IMPLIED> <!ATTLIST variable type CDATA #IMPLIED>
<!ATTLIST variable description CDATA #IMPLIED> <!ATTLIST variable description CDATA #IMPLIED>
<!ATTLIST variable help CDATA #IMPLIED>
<!ATTLIST variable hidden (True|False) "False"> <!ATTLIST variable hidden (True|False) "False">
<!ATTLIST variable disabled (True|False) "False"> <!ATTLIST variable disabled (True|False) "False">
<!ATTLIST variable multi (True|False) "False"> <!ATTLIST variable multi (True|False) "False">
@ -110,6 +104,7 @@
<!ATTLIST variable mode (basic|normal|expert) "normal"> <!ATTLIST variable mode (basic|normal|expert) "normal">
<!ATTLIST variable remove_check (True|False) "False"> <!ATTLIST variable remove_check (True|False) "False">
<!ATTLIST variable remove_condition (True|False) "False"> <!ATTLIST variable remove_condition (True|False) "False">
<!ATTLIST variable remove_fill (True|False) "False">
<!ATTLIST variable test CDATA #IMPLIED> <!ATTLIST variable test CDATA #IMPLIED>
<!ELEMENT separators (separator*)> <!ELEMENT separators (separator*)>
@ -138,10 +133,11 @@
<!ELEMENT group (follower+)> <!ELEMENT group (follower+)>
<!ATTLIST group leader CDATA #REQUIRED> <!ATTLIST group leader CDATA #REQUIRED>
<!ATTLIST group name CDATA #IMPLIED>
<!ATTLIST group description CDATA #IMPLIED> <!ATTLIST group description CDATA #IMPLIED>
<!ELEMENT param (#PCDATA)> <!ELEMENT param (#PCDATA)>
<!ATTLIST param type (string|variable|number|python) "string"> <!ATTLIST param type (string|number|variable|information|suffix) "string">
<!ATTLIST param name CDATA #IMPLIED> <!ATTLIST param name CDATA #IMPLIED>
<!ATTLIST param notraisepropertyerror (True|False) "False"> <!ATTLIST param notraisepropertyerror (True|False) "False">
<!ATTLIST param optional (True|False) "False"> <!ATTLIST param optional (True|False) "False">
@ -151,5 +147,3 @@
<!ATTLIST target optional (True|False) "False"> <!ATTLIST target optional (True|False) "False">
<!ELEMENT follower (#PCDATA)> <!ELEMENT follower (#PCDATA)>
<!ELEMENT help ((variable* | family*)*)>

View File

@ -1,20 +1,25 @@
""" """
Creole flattener. Takes a bunch of Creole XML dispatched in differents folders Takes a bunch of Creole XML dispatched in differents folders
as an input and outputs a human readable flatened XML as an input and outputs a Tiramisu's file
Sample usage:: Sample usage::
eolobj.space_visitor(func)
xml = eolobj.save()
>>> from rougail.objspace import CreoleObjSpace >>> from rougail.objspace import CreoleObjSpace
>>> eolobj = CreoleObjSpace('/usr/share/rougail/rougail.dtd') >>> eolobj = CreoleObjSpace('/usr/share/rougail/rougail.dtd')
>>> eolobj.create_or_populate_from_xml('rougail', ['/usr/share/eole/rougail/dicos']) >>> eolobj.create_or_populate_from_xml('rougail', ['/usr/share/rougail/dicos'])
>>> eolobj.space_visitor() >>> eolobj.space_visitor('/usr/share/rougail/funcs.py')
>>> eolobj.save('/tmp/rougail_flatened_output.xml') >>> tiramisu = eolobj.save()
The CreoleObjSpace The CreoleObjSpace
- loads the XML into an internal CreoleObjSpace representation - loads the XML into an internal CreoleObjSpace representation
- visits/annotates the objects - visits/annotates the objects
- dumps the object space as XML output into a single XML target - dumps the object space as Tiramisu string
The visit/annotation stage is a complex step that corresponds to the Creole The visit/annotation stage is a complex step that corresponds to the Creole
procedures. procedures.
@ -23,11 +28,9 @@ For example: a variable is redefined and shall be moved to another family
means that a variable1 = Variable() object in the object space who lives in the family1 parent means that a variable1 = Variable() object in the object space who lives in the family1 parent
has to be moved in family2. The visit procedure changes the varable1's object space's parent. has to be moved in family2. The visit procedure changes the varable1's object space's parent.
""" """
from lxml.etree import Element, SubElement # pylint: disable=E0611
from .i18n import _ from .i18n import _
from .xmlreflector import XMLReflector from .xmlreflector import XMLReflector
from .annotator import ERASED_ATTRIBUTES, SpaceAnnotator from .annotator import SpaceAnnotator
from .tiramisureflector import TiramisuReflector from .tiramisureflector import TiramisuReflector
from .utils import normalize_family from .utils import normalize_family
from .error import OperationError, SpaceObjShallNotBeUpdated, DictConsistencyError from .error import OperationError, SpaceObjShallNotBeUpdated, DictConsistencyError
@ -41,25 +44,28 @@ FORCE_UNREDEFINABLES = ('value',)
# CreoleObjSpace's elements that shall be set to the UnRedefinable type # CreoleObjSpace's elements that shall be set to the UnRedefinable type
UNREDEFINABLE = ('multi', 'type') UNREDEFINABLE = ('multi', 'type')
CONVERT_PROPERTIES = {'auto_save': ['force_store_value'], 'auto_freeze': ['force_store_value', 'auto_freeze']}
RENAME_ATTIBUTES = {'description': 'doc'}
FORCED_TEXT_ELTS_AS_NAME = ('choice', 'property', 'value', 'target') FORCED_TEXT_ELTS_AS_NAME = ('choice', 'property', 'value', 'target')
CONVERT_EXPORT = {'Leadership': 'leader',
'Variable': 'variable',
'Value': 'value',
'Property': 'property',
'Choice': 'choice',
'Param': 'param',
'Check': 'check',
}
# _____________________________________________________________________________ # _____________________________________________________________________________
# special types definitions for the Object Space's internal representation # special types definitions for the Object Space's internal representation
class RootCreoleObject: class RootCreoleObject:
"" def __init__(self, xmlfiles):
if not isinstance(xmlfiles, list):
xmlfiles = [xmlfiles]
self.xmlfiles = xmlfiles
class Atom(RootCreoleObject):
pass
class Redefinable(RootCreoleObject):
pass
class UnRedefinable(RootCreoleObject):
pass
class CreoleObjSpace: class CreoleObjSpace:
@ -74,11 +80,6 @@ class CreoleObjSpace:
an Object Space's atom object is present only once in the an Object Space's atom object is present only once in the
object space's tree object space's tree
""" """
Atom = type('Atom', (RootCreoleObject,), dict())
"A variable that can't be redefined"
Redefinable = type('Redefinable', (RootCreoleObject,), dict())
"A variable can be redefined"
UnRedefinable = type('UnRedefinable', (RootCreoleObject,), dict())
def __init__(self, dtdfilename): # pylint: disable=R0912 def __init__(self, dtdfilename): # pylint: disable=R0912
@ -112,25 +113,25 @@ class CreoleObjSpace:
for dtd_elt in self.xmlreflector.dtd.iterelements(): for dtd_elt in self.xmlreflector.dtd.iterelements():
attrs = {} attrs = {}
if dtd_elt.name in FORCE_REDEFINABLES: if dtd_elt.name in FORCE_REDEFINABLES:
clstype = self.Redefinable clstype = Redefinable
elif not dtd_elt.attributes() and dtd_elt.name not in FORCE_UNREDEFINABLES:
clstype = Atom
else: else:
clstype = self.UnRedefinable clstype = UnRedefinable
atomic = dtd_elt.name not in FORCE_UNREDEFINABLES and dtd_elt.name not in FORCE_REDEFINABLES
forced_text_elt = dtd_elt.type == 'mixed' forced_text_elt = dtd_elt.type == 'mixed'
for dtd_attr in dtd_elt.iterattributes(): for dtd_attr in dtd_elt.iterattributes():
atomic = False if set(dtd_attr.itervalues()) == {'True', 'False'}:
if set(dtd_attr.itervalues()) == set(['True', 'False']):
# it's a boolean # it's a boolean
self.booleans_attributs.append(dtd_attr.name) self.booleans_attributs.append(dtd_attr.name)
if dtd_attr.default_value: if dtd_attr.default_value:
# set default value for this attribute # set default value for this attribute
default_value = dtd_attr.default_value default_value = dtd_attr.default_value
if dtd_attr.name in self.booleans_attributs: if dtd_attr.name in self.booleans_attributs:
default_value = self.convert_boolean(dtd_attr.default_value) default_value = self.convert_boolean(default_value)
attrs[dtd_attr.name] = default_value attrs[dtd_attr.name] = default_value
if dtd_attr.name == 'redefine': if dtd_attr.name == 'redefine':
# has a redefine attribute, so it's a Redefinable object # has a redefine attribute, so it's a Redefinable object
clstype = self.Redefinable clstype = Redefinable
if dtd_attr.name == 'name' and forced_text_elt: if dtd_attr.name == 'name' and forced_text_elt:
# child.text should be transform has a "name" attribute # child.text should be transform has a "name" attribute
self.forced_text_elts.add(dtd_elt.name) self.forced_text_elts.add(dtd_elt.name)
@ -138,16 +139,14 @@ class CreoleObjSpace:
if forced_text_elt is True: if forced_text_elt is True:
self.forced_text_elts_as_name.add(dtd_elt.name) self.forced_text_elts_as_name.add(dtd_elt.name)
if atomic:
# has any attribute so it's an Atomic object
clstype = self.Atom
# create ObjectSpace object # create ObjectSpace object
setattr(self, dtd_elt.name, type(dtd_elt.name.capitalize(), (clstype,), attrs)) setattr(self, dtd_elt.name, type(dtd_elt.name.capitalize(), (clstype,), attrs))
def create_or_populate_from_xml(self, def create_or_populate_from_xml(self,
namespace, namespace,
xmlfolders): xmlfolders,
):
"""Parses a bunch of XML files """Parses a bunch of XML files
populates the CreoleObjSpace populates the CreoleObjSpace
""" """
@ -155,12 +154,14 @@ class CreoleObjSpace:
self.redefine_variables = [] self.redefine_variables = []
self.check_removed = [] self.check_removed = []
self.condition_removed = [] self.condition_removed = []
self.xml_parse_document(document, self.xml_parse_document(xmlfile,
document,
self.space, self.space,
namespace, namespace,
) )
def xml_parse_document(self, def xml_parse_document(self,
xmlfile,
document, document,
space, space,
namespace, namespace,
@ -168,175 +169,157 @@ class CreoleObjSpace:
"""Parses a Creole XML file """Parses a Creole XML file
populates the CreoleObjSpace populates the CreoleObjSpace
""" """
# var to check unique family name in a XML file
family_names = [] family_names = []
for child in document: for child in document:
# this index enables us to reorder objects # this index enables us to reorder objects
self.index += 1
# doesn't proceed the XML commentaries
if not isinstance(child.tag, str): if not isinstance(child.tag, str):
# doesn't proceed the XML commentaries
continue continue
if child.tag == 'family': if child.tag == 'family':
if child.attrib['name'] in family_names: if child.attrib['name'] in family_names:
raise DictConsistencyError(_('Family {} is set several times').format(child.attrib['name'])) raise DictConsistencyError(_(f'Family "{child.attrib["name"]}" is set several times in "{xmlfile}"'))
family_names.append(child.attrib['name']) family_names.append(child.attrib['name'])
if child.tag == 'variables': if child.tag == 'variables':
# variables has no name, so force namespace name
child.attrib['name'] = namespace child.attrib['name'] = namespace
if child.tag == 'value' and child.text == None: if child.tag == 'value' and child.text is None:
# FIXME should not be here
continue continue
# variable objects creation # variable objects creation
try: try:
variableobj = self.generate_variableobj(child, variableobj = self.get_variableobj(xmlfile,
space, child,
namespace, space,
) namespace,
)
except SpaceObjShallNotBeUpdated: except SpaceObjShallNotBeUpdated:
continue continue
self.set_text_to_obj(child, self.index += 1
variableobj, self.set_text(child,
) variableobj,
self.set_xml_attributes_to_obj(child, )
variableobj, self.set_attributes(xmlfile,
) child,
self.variableobj_tree_visitor(child, variableobj,
variableobj, )
namespace, self.remove(child,
) variableobj,
self.fill_variableobj_path_attribute(space, )
child, self.set_path(space,
namespace, child,
document, namespace,
variableobj, document,
) variableobj,
)
self.add_to_tree_structure(variableobj, self.add_to_tree_structure(variableobj,
space, space,
child, child,
namespace,
) )
if list(child) != []: if list(child) != []:
self.xml_parse_document(child, self.xml_parse_document(xmlfile,
child,
variableobj, variableobj,
namespace, namespace,
) )
def generate_variableobj(self, def get_variableobj(self,
child, xmlfile: str,
space, child: list,
namespace, space,
): namespace,
):
""" """
instanciates or creates Creole Object Subspace objects instanciates or creates Creole Object Subspace objects
""" """
variableobj = getattr(self, child.tag)() obj = getattr(self, child.tag)
if isinstance(variableobj, self.Redefinable): if Redefinable in obj.__mro__:
variableobj = self.create_or_update_redefinable_object(child.attrib, return self.create_or_update_redefinable_object(xmlfile,
space, child.attrib,
child, space,
namespace, child,
) namespace,
elif isinstance(variableobj, self.Atom) and child.tag in vars(space): )
# instanciates an object from the CreoleObjSpace's builtins types elif Atom in obj.__mro__:
# example : child.tag = constraints -> a self.Constraints() object is created if child.tag in vars(space):
# this Atom instance has to be a singleton here # Atom instance has to be a singleton here
# we do not re-create it, we reuse it # we do not re-create it, we reuse it
variableobj = getattr(space, child.tag) return getattr(space, child.tag)
self.create_tree_structure(space, return obj(xmlfile)
child, if child.tag not in vars(space):
variableobj, setattr(space, child.tag, [])
) return obj(xmlfile)
return variableobj
def create_or_update_redefinable_object(self, def create_or_update_redefinable_object(self,
xmlfile,
subspace, subspace,
space, space,
child, child,
namespace, namespace,
): ):
"""Creates or retrieves the space object that corresponds
to the `child` XML object
Two attributes of the `child` XML object are important:
- with the `redefine` boolean flag attribute we know whether
the corresponding space object shall be created or updated
- `True` means that the corresponding space object shall be updated
- `False` means that the corresponding space object shall be created
- with the `exists` boolean flag attribute we know whether
the corresponding space object shall be created
(or nothing -- that is the space object isn't modified)
- `True` means that the corresponding space object shall be created
- `False` means that the corresponding space object is not updated
In the special case `redefine` is True and `exists` is False,
we create the corresponding space object if it doesn't exist
and we update it if it exists.
:return: the corresponding space object of the `child` XML object
"""
if child.tag in self.forced_text_elts_as_name: if child.tag in self.forced_text_elts_as_name:
name = child.text name = child.text
else: else:
name = subspace['name'] name = subspace['name']
if self.is_already_exists(name, if child.tag == 'family':
space, name = normalize_family(name)
child, existed_var = self.get_existed_obj(name,
namespace, space,
): child,
namespace,
)
if existed_var:
# if redefine is set to object, default value is False
# otherwise it's always a redefinable object
default_redefine = child.tag in FORCE_REDEFINABLES default_redefine = child.tag in FORCE_REDEFINABLES
redefine = self.convert_boolean(subspace.get('redefine', default_redefine)) redefine = self.convert_boolean(subspace.get('redefine', default_redefine))
exists = self.convert_boolean(subspace.get('exists', True))
if redefine is True: if redefine is True:
return self.translate_in_space(name, existed_var.xmlfiles.append(xmlfile)
space, return existed_var
child, exists = self.convert_boolean(subspace.get('exists', True))
namespace, if exists is False:
)
elif exists is False:
raise SpaceObjShallNotBeUpdated() raise SpaceObjShallNotBeUpdated()
raise DictConsistencyError(_(f'Already present in another XML file, {name} cannot be re-created')) xmlfiles = self.display_xmlfiles(existed_var.xmlfiles)
redefine = self.convert_boolean(subspace.get('redefine', False)) raise DictConsistencyError(_(f'"{child.tag}" named "{name}" cannot be re-created in "{xmlfile}", already defined in {xmlfiles}'))
# if this object must only be modified if object already exists
exists = self.convert_boolean(subspace.get('exists', False)) exists = self.convert_boolean(subspace.get('exists', False))
if redefine is False or exists is True: if exists is True:
return getattr(self, child.tag)() raise SpaceObjShallNotBeUpdated()
raise DictConsistencyError(_(f'Redefined object: {name} does not exist yet')) redefine = self.convert_boolean(subspace.get('redefine', False))
if redefine is False:
if child.tag not in vars(space):
setattr(space, child.tag, {})
return getattr(self, child.tag)(xmlfile)
raise DictConsistencyError(_(f'Redefined object in "{xmlfile}": "{name}" does not exist yet'))
def create_tree_structure(self, def display_xmlfiles(self,
space, xmlfiles: list,
child, ) -> str:
variableobj, if len(xmlfiles) == 1:
): # pylint: disable=R0201 return '"' + xmlfiles[0] + '"'
""" return '"' + '", "'.join(xmlfiles[:-1]) + '"' + ' and ' + '"' + xmlfiles[-1] + '"'
Builds the tree structure of the object space here
we set services attributes in order to be populated later on
for example::
space = Family() def get_existed_obj(self,
space.variable = dict() name: str,
another example: space: str,
space = Variable() child,
space.value = list() namespace: str,
""" ):
if child.tag not in vars(space):
if isinstance(variableobj, self.Redefinable):
setattr(space, child.tag, dict())
elif isinstance(variableobj, self.UnRedefinable):
setattr(space, child.tag, [])
elif not isinstance(variableobj, self.Atom): # pragma: no cover
raise OperationError(_("Creole object {} "
"has a wrong type").format(type(variableobj)))
def is_already_exists(self, name, space, child, namespace):
if isinstance(space, self.family): # pylint: disable=E1101 if isinstance(space, self.family): # pylint: disable=E1101
if namespace != Config['variable_namespace']: if namespace != Config['variable_namespace']:
name = space.path + '.' + name name = space.path + '.' + name
return self.paths.path_is_defined(name) if self.paths.path_is_defined(name):
if child.tag == 'family': old_family_name = self.paths.get_variable_family_name(name)
norm_name = normalize_family(name) if namespace != Config['variable_namespace']:
else: old_family_name = namespace + '.' + old_family_name
norm_name = name if space.path != old_family_name:
return norm_name in getattr(space, child.tag, {}) xmlfiles = self.display_xmlfiles(space.xmlfiles)
raise DictConsistencyError(_(f'Variable was previously create in family "{old_family_name}", now it is in "{space.path}" in {xmlfiles}'))
return self.paths.get_variable_obj(name)
return
children = getattr(space, child.tag, {})
if name in children:
return children[name]
def convert_boolean(self, value): # pylint: disable=R0201 def convert_boolean(self, value): # pylint: disable=R0201
"""Boolean coercion. The Creole XML may contain srings like `True` or `False` """Boolean coercion. The Creole XML may contain srings like `True` or `False`
@ -347,41 +330,59 @@ class CreoleObjSpace:
return True return True
elif value == 'False': elif value == 'False':
return False return False
else: raise TypeError(_('{} is not True or False').format(value)) # pragma: no cover
raise TypeError(_('{} is not True or False').format(value)) # pragma: no cover
def translate_in_space(self, def set_text(self,
name, child,
family, variableobj,
variable, ):
namespace, if child.text is None:
): return
if not isinstance(family, self.family): # pylint: disable=E1101 text = child.text.strip()
if variable.tag == 'family': if not text:
norm_name = normalize_family(name) return
else: if child.tag in self.forced_text_elts_as_name:
norm_name = name variableobj.name = text
return getattr(family, variable.tag)[norm_name]
if namespace == Config['variable_namespace']:
path = name
else: else:
path = family.path + '.' + name variableobj.text = text
old_family_name = self.paths.get_variable_family_name(path)
if normalize_family(family.name) == old_family_name: def set_attributes(self,
return getattr(family, variable.tag)[name] xmlfile,
old_family = self.space.variables[Config['variable_namespace']].family[old_family_name] # pylint: disable=E1101 child,
variable_obj = old_family.variable[name] variableobj,
del old_family.variable[name] ):
if 'variable' not in vars(family): redefine = self.convert_boolean(child.attrib.get('redefine', False))
family.variable = dict() if redefine and child.tag == 'variable':
family.variable[name] = variable_obj # delete old values
self.paths.add_variable(namespace, has_value = hasattr(variableobj, 'value')
name, if has_value and len(child) != 0:
family.name, del variableobj.value
False, for attr, val in child.attrib.items():
variable_obj, if redefine and attr in UNREDEFINABLE:
) xmlfiles = self.display_xmlfiles(variableobj.xmlfiles[:-1])
return variable_obj raise DictConsistencyError(_(f'cannot redefine attribute "{attr}" for variable "{child.attrib["name"]}" in "{xmlfile}", already defined in {xmlfiles}'))
if attr in self.booleans_attributs:
val = self.convert_boolean(val)
if attr == 'name' and getattr(variableobj, 'name', None):
# do not redefine name
continue
setattr(variableobj, attr, val)
def remove(self,
child,
variableobj,
):
"""Creole object tree manipulations
"""
if child.tag == 'variable':
if child.attrib.get('remove_check', False):
self.remove_check(variableobj.name)
if child.attrib.get('remove_condition', False):
self.remove_condition(variableobj.name)
if child.attrib.get('remove_fill', False):
self.remove_fill(variableobj.name)
if child.tag == 'fill' and child.attrib['target'] in self.redefine_variables:
self.remove_fill(child.attrib['target'])
def remove_check(self, name): # pylint: disable=C0111 def remove_check(self, name): # pylint: disable=C0111
if hasattr(self.space, 'constraints') and hasattr(self.space.constraints, 'check'): if hasattr(self.space, 'constraints') and hasattr(self.space.constraints, 'check'):
@ -396,110 +397,43 @@ class CreoleObjSpace:
self.space.constraints.check.pop(idx) # pylint: disable=E1101 self.space.constraints.check.pop(idx) # pylint: disable=E1101
def remove_condition(self, name): # pylint: disable=C0111 def remove_condition(self, name): # pylint: disable=C0111
remove_conditions = []
for idx, condition in enumerate(self.space.constraints.condition): # pylint: disable=E1101 for idx, condition in enumerate(self.space.constraints.condition): # pylint: disable=E1101
remove_targets = [] if condition.source == name:
if hasattr(condition, 'target'): remove_conditions.append(idx)
for target_idx, target in enumerate(condition.target): for idx in remove_conditions:
if target.name == name: del self.space.constraints.condition[idx]
remove_targets.append(target_idx)
remove_targets = list(set(remove_targets))
remove_targets.sort(reverse=True)
for idx in remove_targets:
del condition.target[idx]
def add_to_tree_structure(self, def remove_fill(self, name): # pylint: disable=C0111
variableobj, if hasattr(self.space, 'constraints') and hasattr(self.space.constraints, 'fill'):
space, remove_fills= []
child, for idx, fill in enumerate(self.space.constraints.fill): # pylint: disable=E1101
): # pylint: disable=R0201 if hasattr(fill, 'target') and fill.target == name:
if isinstance(variableobj, self.Redefinable): remove_fills.append(idx)
name = variableobj.name
if child.tag == 'family':
name = normalize_family(name)
getattr(space, child.tag)[name] = variableobj
elif isinstance(variableobj, self.UnRedefinable):
getattr(space, child.tag).append(variableobj)
else:
setattr(space, child.tag, variableobj)
def set_text_to_obj(self, remove_fills = list(set(remove_fills))
child, remove_fills.sort(reverse=True)
variableobj, for idx in remove_fills:
): self.space.constraints.fill.pop(idx) # pylint: disable=E1101
if child.text is None:
text = None
else:
text = child.text.strip()
if text:
if child.tag in self.forced_text_elts_as_name:
variableobj.name = text
else:
variableobj.text = text
def set_xml_attributes_to_obj(self, def set_path(self,
child, space,
variableobj, child,
): namespace,
redefine = self.convert_boolean(child.attrib.get('redefine', False)) document,
has_value = hasattr(variableobj, 'value') variableobj,
if redefine is True and child.tag == 'variable' and has_value and len(child) != 0: ): # pylint: disable=R0913
del variableobj.value
for attr, val in child.attrib.items():
if redefine and attr in UNREDEFINABLE:
# UNREDEFINABLE concerns only 'variable' node so we can fix name
# to child.attrib['name']
name = child.attrib['name']
raise DictConsistencyError(_(f'cannot redefine attribute {attr} for variable {name}'))
if attr in self.booleans_attributs:
val = self.convert_boolean(val)
if not (attr == 'name' and getattr(variableobj, 'name', None) != None):
setattr(variableobj, attr, val)
keys = list(vars(variableobj).keys())
def variableobj_tree_visitor(self,
child,
variableobj,
namespace,
):
"""Creole object tree manipulations
"""
if child.tag == 'variable':
if child.attrib.get('remove_check', False):
self.remove_check(variableobj.name)
if child.attrib.get('remove_condition', False):
self.remove_condition(variableobj.name)
if child.tag == 'fill':
# if variable is a redefine in current dictionary
# XXX not working with variable not in variable and in leader/followers
variableobj.redefine = child.attrib['target'] in self.redefine_variables
if not hasattr(variableobj, 'index'):
variableobj.index = self.index
if child.tag == 'check' and child.attrib['target'] in self.redefine_variables and child.attrib['target'] not in self.check_removed:
self.remove_check(child.attrib['target'])
self.check_removed.append(child.attrib['target'])
if child.tag == 'condition' and child.attrib['source'] in self.redefine_variables and child.attrib['source'] not in self.check_removed:
self.remove_condition(child.attrib['source'])
self.condition_removed.append(child.attrib['source'])
variableobj.namespace = namespace
def fill_variableobj_path_attribute(self,
space,
child,
namespace,
document,
variableobj,
): # pylint: disable=R0913
"""Fill self.paths attributes """Fill self.paths attributes
""" """
if isinstance(space, self.help): # pylint: disable=E1101
return
if child.tag == 'variable': if child.tag == 'variable':
family_name = normalize_family(document.attrib['name']) family_name = document.attrib['name']
family_name = normalize_family(family_name)
self.paths.add_variable(namespace, self.paths.add_variable(namespace,
child.attrib['name'], child.attrib['name'],
family_name, family_name,
document.attrib.get('dynamic') != None, document.attrib.get('dynamic') != None,
variableobj) variableobj,
)
if child.attrib.get('redefine', 'False') == 'True': if child.attrib.get('redefine', 'False') == 'True':
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
self.redefine_variables.append(child.attrib['name']) self.redefine_variables.append(child.attrib['name'])
@ -517,6 +451,25 @@ class CreoleObjSpace:
) )
variableobj.path = self.paths.get_family_path(family_name, namespace) variableobj.path = self.paths.get_family_path(family_name, namespace)
def add_to_tree_structure(self,
variableobj,
space,
child,
namespace,
): # pylint: disable=R0201
if not hasattr(variableobj, 'index'):
variableobj.index = self.index
variableobj.namespace = namespace
if isinstance(variableobj, Redefinable):
name = variableobj.name
if child.tag == 'family':
name = normalize_family(name)
getattr(space, child.tag)[name] = variableobj
elif isinstance(variableobj, UnRedefinable):
getattr(space, child.tag).append(variableobj)
else:
setattr(space, child.tag, variableobj)
def space_visitor(self, eosfunc_file): # pylint: disable=C0111 def space_visitor(self, eosfunc_file): # pylint: disable=C0111
self.funcs_path = eosfunc_file self.funcs_path = eosfunc_file
SpaceAnnotator(self, eosfunc_file) SpaceAnnotator(self, eosfunc_file)

View File

@ -13,7 +13,8 @@ class Path:
def __init__(self): def __init__(self):
self.variables = {} self.variables = {}
self.families = {} self.families = {}
self.full_paths = {} self.full_paths_families = {}
self.full_paths_variables = {}
# Family # Family
def add_family(self, def add_family(self,
@ -23,7 +24,7 @@ class Path:
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if '.' not in name and namespace == Config['variable_namespace']: if '.' not in name and namespace == Config['variable_namespace']:
full_name = '.'.join([namespace, name]) full_name = '.'.join([namespace, name])
self.full_paths[name] = full_name self.full_paths_families[name] = full_name
else: else:
full_name = name full_name = name
if full_name in self.families and self.families[full_name]['variableobj'] != variableobj: if full_name in self.families and self.families[full_name]['variableobj'] != variableobj:
@ -37,12 +38,9 @@ class Path:
name: str, name: str,
current_namespace: str, current_namespace: str,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
name = normalize_family(name, #name = normalize_family(name)
check_name=False, if '.' not in name and current_namespace == Config['variable_namespace'] and name in self.full_paths_families:
allow_dot=True, name = self.full_paths_families[name]
)
if '.' not in name and current_namespace == Config['variable_namespace'] and name in self.full_paths:
name = self.full_paths[name]
if current_namespace is None: # pragma: no cover if current_namespace is None: # pragma: no cover
raise OperationError('current_namespace must not be None') raise OperationError('current_namespace must not be None')
dico = self.families[name] dico = self.families[name]
@ -55,8 +53,8 @@ class Path:
def get_family_obj(self, def get_family_obj(self,
name: str, name: str,
) -> 'Family': # pylint: disable=C0111 ) -> 'Family': # pylint: disable=C0111
if '.' not in name and name in self.full_paths: if '.' not in name and name in self.full_paths_families:
name = self.full_paths[name] name = self.full_paths_families[name]
if name not in self.families: if name not in self.families:
raise DictConsistencyError(_('unknown family {}').format(name)) raise DictConsistencyError(_('unknown family {}').format(name))
dico = self.families[name] dico = self.families[name]
@ -65,7 +63,7 @@ class Path:
def family_is_defined(self, def family_is_defined(self,
name: str, name: str,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if '.' not in name and name not in self.families and name in self.full_paths: if '.' not in name and name not in self.families and name in self.full_paths_families:
return True return True
return name in self.families return name in self.families
@ -88,7 +86,7 @@ class Path:
dico['variableobj'], dico['variableobj'],
) )
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
self.full_paths[name] = new_path self.full_paths_variables[name] = new_path
else: else:
name = new_path name = new_path
dico = self._get_variable(name) dico = self._get_variable(name)
@ -110,7 +108,7 @@ class Path:
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if '.' not in name: if '.' not in name:
full_name = '.'.join([namespace, family, name]) full_name = '.'.join([namespace, family, name])
self.full_paths[name] = full_name self.full_paths_variables[name] = full_name
else: else:
full_name = name full_name = name
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
@ -176,7 +174,7 @@ class Path:
def path_is_defined(self, def path_is_defined(self,
name: str, name: str,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if '.' not in name and name not in self.variables and name in self.full_paths: if '.' not in name and name not in self.variables and name in self.full_paths_variables:
return True return True
return name in self.variables return name in self.variables
@ -186,17 +184,21 @@ class Path:
) -> str: ) -> str:
if name not in self.variables: if name not in self.variables:
if name not in self.variables: if name not in self.variables:
if '.' not in name and name in self.full_paths: if '.' not in name and name in self.full_paths_variables:
name = self.full_paths[name] name = self.full_paths_variables[name]
if name not in self.variables: if name not in self.variables:
for var_name, variable in self.variables.items(): for var_name, variable in self.variables.items():
if variable['is_dynamic'] and name.startswith(var_name): if variable['is_dynamic'] and name.startswith(var_name):
if not with_suffix:
raise Exception('This option is dynamic, should use "with_suffix" attribute')
return variable, name[len(var_name):] return variable, name[len(var_name):]
if '.' not in name: if '.' not in name:
for var_name, path in self.full_paths.items(): for var_name, path in self.full_paths_variables.items():
if name.startswith(var_name): if name.startswith(var_name):
variable = self.variables[self.full_paths[var_name]] variable = self.variables[self.full_paths_variables[var_name]]
if variable['is_dynamic']: if variable['is_dynamic']:
if not with_suffix:
raise Exception('This option is dynamic, should use "with_suffix" attribute')
return variable, name[len(var_name):] return variable, name[len(var_name):]
raise DictConsistencyError(_('unknown option {}').format(name)) raise DictConsistencyError(_('unknown option {}').format(name))
if with_suffix: if with_suffix:

View File

@ -4,13 +4,13 @@ Gestion du mini-langage de template
On travaille sur les fichiers cibles On travaille sur les fichiers cibles
""" """
import imp from importlib.machinery import SourceFileLoader
from shutil import copy from shutil import copy
import logging import logging
from typing import Dict, Any from typing import Dict, Any
from subprocess import call from subprocess import call
from os import listdir, makedirs from os import listdir, makedirs, getcwd, chdir
from os.path import dirname, join, isfile from os.path import dirname, join, isfile, abspath, normpath, relpath
from Cheetah.Template import Template as ChtTemplate from Cheetah.Template import Template as ChtTemplate
from Cheetah.NameMapper import NotFound as CheetahNotFound from Cheetah.NameMapper import NotFound as CheetahNotFound
@ -79,7 +79,8 @@ class CheetahTemplate(ChtTemplate):
context, context,
eosfunc: Dict, eosfunc: Dict,
destfilename, destfilename,
variable): variable,
):
"""Initialize Creole CheetahTemplate """Initialize Creole CheetahTemplate
""" """
extra_context = {'is_defined' : IsDefined(context), extra_context = {'is_defined' : IsDefined(context),
@ -92,6 +93,24 @@ class CheetahTemplate(ChtTemplate):
file=filename, file=filename,
searchList=[context, eosfunc, extra_context]) searchList=[context, eosfunc, extra_context])
# FORK of Cheetah fonction, do not replace '\\' by '/'
def serverSidePath(self,
path=None,
normpath=normpath,
abspath=abspath
):
# strange...
if path is None and isinstance(self, str):
path = self
if path:
return normpath(abspath(path))
# return normpath(abspath(path.replace("\\", '/')))
elif hasattr(self, '_filePath') and self._filePath:
return normpath(abspath(self._filePath))
else:
return None
class CreoleLeader: class CreoleLeader:
def __init__(self, value, follower=None, index=None): def __init__(self, value, follower=None, index=None):
@ -233,7 +252,7 @@ class CreoleTemplateEngine:
self.distrib_dir = distrib_dir self.distrib_dir = distrib_dir
eos = {} eos = {}
if eosfunc_file is not None: if eosfunc_file is not None:
eosfunc = imp.load_source('eosfunc', eosfunc_file) eosfunc = SourceFileLoader('eosfunc', eosfunc_file).load_module()
for func in dir(eosfunc): for func in dir(eosfunc):
if not func.startswith('_'): if not func.startswith('_'):
eos[func] = getattr(eosfunc, func) eos[func] = getattr(eosfunc, func)
@ -287,37 +306,43 @@ class CreoleTemplateEngine:
return CreoleExtra(families) return CreoleExtra(families)
def patch_template(self, def patch_template(self,
filename: str): filename: str,
tmp_dir: str,
patch_dir: str,
) -> None:
"""Apply patch to a template """Apply patch to a template
""" """
patch_cmd = ['patch', '-d', self.tmp_dir, '-N', '-p1'] patch_cmd = ['patch', '-d', tmp_dir, '-N', '-p1']
patch_no_debug = ['-s', '-r', '-', '--backup-if-mismatch'] patch_no_debug = ['-s', '-r', '-', '--backup-if-mismatch']
# patches variante + locaux patch_file = join(patch_dir, f'{filename}.patch')
for directory in [join(Config['patch_dir'], 'variante'), Config['patch_dir']]: if isfile(patch_file):
patch_file = join(directory, f'{filename}.patch') log.info(_("Patching template '{filename}' with '{patch_file}'"))
if isfile(patch_file): rel_patch_file = relpath(patch_file, tmp_dir)
log.info(_("Patching template '{filename}' with '{patch_file}'")) ret = call(patch_cmd + patch_no_debug + ['-i', rel_patch_file])
ret = call(patch_cmd + patch_no_debug + ['-i', patch_file]) if ret:
if ret: patch_cmd_err = ' '.join(patch_cmd + ['-i', rel_patch_file])
patch_cmd_err = ' '.join(patch_cmd + ['-i', patch_file]) log.error(_(f"Error applying patch: '{rel_patch_file}'\nTo reproduce and fix this error {patch_cmd_err}"))
log.error(_(f"Error applying patch: '{patch_file}'\nTo reproduce and fix this error {patch_cmd_err}")) copy(join(self.distrib_dir, filename), tmp_dir)
copy(filename, self.tmp_dir)
def prepare_template(self, def prepare_template(self,
filename: str): filename: str,
tmp_dir: str,
patch_dir: str,
) -> None:
"""Prepare template source file """Prepare template source file
""" """
log.info(_("Copy template: '{filename}' -> '{self.tmp_dir}'")) log.info(_("Copy template: '{filename}' -> '{tmp_dir}'"))
copy(filename, self.tmp_dir) copy(filename, tmp_dir)
self.patch_template(filename) self.patch_template(filename, tmp_dir, patch_dir)
def process(self, def process(self,
source: str, source: str,
true_destfilename: str, true_destfilename: str,
destfilename: str, destfilename: str,
filevar: Dict, filevar: Dict,
variable: Any): variable: Any,
):
"""Process a cheetah template """Process a cheetah template
""" """
# full path of the destination file # full path of the destination file
@ -332,16 +357,19 @@ class CreoleTemplateEngine:
data = str(cheetah_template) data = str(cheetah_template)
except CheetahNotFound as err: except CheetahNotFound as err:
varname = err.args[0][13:-1] varname = err.args[0][13:-1]
raise TemplateError(_(f"Error: unknown variable used in template {destfilename} : {varname}")) raise TemplateError(_(f"Error: unknown variable used in template {source} to {destfilename} : {varname}"))
except Exception as err: except Exception as err:
raise TemplateError(_(f"Error while instantiating template {destfilename}: {err}")) raise TemplateError(_(f"Error while instantiating template {source} to {destfilename}: {err}"))
with open(destfilename, 'w') as file_h: with open(destfilename, 'w') as file_h:
file_h.write(data) file_h.write(data)
def instance_file(self, def instance_file(self,
filevar: Dict, filevar: Dict,
service_name: str) -> None: service_name: str,
tmp_dir: str,
dest_dir: str,
) -> None:
"""Run templatisation on one file """Run templatisation on one file
""" """
log.info(_("Instantiating file '{filename}'")) log.info(_("Instantiating file '{filename}'"))
@ -355,13 +383,13 @@ class CreoleTemplateEngine:
if variable: if variable:
variable = [variable] variable = [variable]
for idx, filename in enumerate(filenames): for idx, filename in enumerate(filenames):
destfilename = join(self.dest_dir, filename[1:]) destfilename = join(dest_dir, filename[1:])
makedirs(dirname(destfilename), exist_ok=True) makedirs(dirname(destfilename), exist_ok=True)
if variable: if variable:
var = variable[idx] var = variable[idx]
else: else:
var = None var = None
source = join(self.tmp_dir, filevar['source']) source = join(tmp_dir, filevar['source'])
if filevar['templating']: if filevar['templating']:
self.process(source, self.process(source,
filename, filename,
@ -374,6 +402,11 @@ class CreoleTemplateEngine:
async def instance_files(self) -> None: async def instance_files(self) -> None:
"""Run templatisation on all files """Run templatisation on all files
""" """
ori_dir = getcwd()
tmp_dir = relpath(self.tmp_dir, self.distrib_dir)
dest_dir = relpath(self.dest_dir, self.distrib_dir)
patch_dir = relpath(Config['patch_dir'], self.distrib_dir)
chdir(self.distrib_dir)
for option in await self.config.option.list(type='all'): for option in await self.config.option.list(type='all'):
namespace = await option.option.name() namespace = await option.option.name()
if namespace == Config['variable_namespace']: if namespace == Config['variable_namespace']:
@ -382,8 +415,8 @@ class CreoleTemplateEngine:
families = await self.load_eole_variables(namespace, families = await self.load_eole_variables(namespace,
option) option)
self.rougail_variables_dict[namespace] = families self.rougail_variables_dict[namespace] = families
for template in listdir(self.distrib_dir): for template in listdir('.'):
self.prepare_template(join(self.distrib_dir, template)) self.prepare_template(template, tmp_dir, patch_dir)
for service_obj in await self.config.option('services').list('all'): for service_obj in await self.config.option('services').list('all'):
service_name = await service_obj.option.doc() service_name = await service_obj.option.doc()
for fills in await service_obj.list('all'): for fills in await service_obj.list('all'):
@ -391,15 +424,17 @@ class CreoleTemplateEngine:
for fill_obj in await fills.list('all'): for fill_obj in await fills.list('all'):
fill = await fill_obj.value.dict() fill = await fill_obj.value.dict()
filename = fill['source'] filename = fill['source']
distib_file = join(self.distrib_dir, filename) if not isfile(filename):
if not isfile(distib_file): raise FileNotFound(_(f"File {filename} does not exist."))
raise FileNotFound(_(f"File {distib_file} does not exist."))
if fill.get('activate', False): if fill.get('activate', False):
self.instance_file(fill, self.instance_file(fill,
service_name, service_name,
tmp_dir,
dest_dir,
) )
else: else:
log.debug(_("Instantiation of file '{filename}' disabled")) log.debug(_("Instantiation of file '{filename}' disabled"))
chdir(ori_dir)
async def generate(config: Config, async def generate(config: Config,

View File

@ -9,5 +9,4 @@ class ConvertDynOptionDescription(DynOptionDescription):
def convert_suffix_to_path(self, suffix): def convert_suffix_to_path(self, suffix):
if not isinstance(suffix, str): if not isinstance(suffix, str):
suffix = str(suffix) suffix = str(suffix)
return normalize_family(suffix, return normalize_family(suffix)
check_name=False)

View File

@ -4,7 +4,7 @@ flattened XML specific
from .config import Config from .config import Config
from .i18n import _ from .i18n import _
from .error import LoaderError from .error import LoaderError
from .annotator import ERASED_ATTRIBUTES from .annotator import ERASED_ATTRIBUTES, CONVERT_OPTION
FUNC_TO_DICT = ['valid_not_equal'] FUNC_TO_DICT = ['valid_not_equal']
@ -12,45 +12,22 @@ FORCE_INFORMATIONS = ['help', 'test', 'separator', 'manage']
ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi') ATTRIBUTES_ORDER = ('name', 'doc', 'default', 'multi')
CONVERT_OPTION = {'number': dict(opttype="IntOption", func=int),
'choice': dict(opttype="ChoiceOption"),
'string': dict(opttype="StrOption"),
'password': dict(opttype="PasswordOption"),
'mail': dict(opttype="EmailOption"),
'boolean': dict(opttype="BoolOption"),
'symlink': dict(opttype="SymLinkOption"),
'filename': dict(opttype="FilenameOption"),
'date': dict(opttype="DateOption"),
'unix_user': dict(opttype="UsernameOption"),
'ip': dict(opttype="IPOption", initkwargs={'allow_reserved': True}),
'local_ip': dict(opttype="IPOption", initkwargs={'private_only': True, 'warnings_only': True}),
'netmask': dict(opttype="NetmaskOption"),
'network': dict(opttype="NetworkOption"),
'broadcast': dict(opttype="BroadcastOption"),
'netbios': dict(opttype="DomainnameOption", initkwargs={'type': 'netbios', 'warnings_only': True}),
'domain': dict(opttype="DomainnameOption", initkwargs={'type': 'domainname', 'allow_ip': False}),
'hostname': dict(opttype="DomainnameOption", initkwargs={'type': 'hostname', 'allow_ip': False}),
'web_address': dict(opttype="URLOption", initkwargs={'allow_ip': True, 'allow_without_dot': True}),
'port': dict(opttype="PortOption", initkwargs={'allow_private': True}),
'mac': dict(opttype="MACOption"),
'cidr': dict(opttype="IPOption", initkwargs={'cidr': True}),
'network_cidr': dict(opttype="NetworkOption", initkwargs={'cidr': True}),
}
class TiramisuReflector: class TiramisuReflector:
def __init__(self, def __init__(self,
xmlroot, xmlroot,
funcs_path, funcs_path,
): ):
self.storage = ElementStorage() self.storage = ElementStorage()
self.storage.text = ["try:", self.storage.text = ["from importlib.machinery import SourceFileLoader",
f"func = SourceFileLoader('func', '{funcs_path}').load_module()",
"for key, value in dict(locals()).items():",
" if key != ['SourceFileLoader', 'func']:",
" setattr(func, key, value)",
"try:",
" from tiramisu3 import *", " from tiramisu3 import *",
"except:", "except:",
" from tiramisu import *", " from tiramisu import *",
"from rougail.tiramisu import ConvertDynOptionDescription", "from rougail.tiramisu import ConvertDynOptionDescription",
"import imp",
f"func = imp.load_source('func', '{funcs_path}')",
] ]
self.make_tiramisu_objects(xmlroot) self.make_tiramisu_objects(xmlroot)
# parse object # parse object
@ -252,7 +229,7 @@ class Common:
if not self.attrib[key]: if not self.attrib[key]:
continue continue
value = "frozenset({" + self.attrib[key] + "})" value = "frozenset({" + self.attrib[key] + "})"
elif key in ['default', 'multi', 'suffixes', 'validators']: elif key in ['default', 'multi', 'suffixes', 'validators', 'values']:
value = self.attrib[key] value = self.attrib[key]
elif isinstance(value, str) and key != 'opt' and not value.startswith('['): elif isinstance(value, str) and key != 'opt' and not value.startswith('['):
value = "'" + value.replace("'", "\\\'") + "'" value = "'" + value.replace("'", "\\\'") + "'"
@ -341,6 +318,8 @@ class Variable(Common):
value = value.split(',') value = value.split(',')
if self.object_type == 'IntOption': if self.object_type == 'IntOption':
value = [int(v) for v in value] value = [int(v) for v in value]
elif self.object_type == 'FloatOption':
value = [float(v) for v in value]
self.informations[key] = value self.informations[key] = value
else: else:
self.attrib[key] = value self.attrib[key] = value
@ -368,9 +347,16 @@ class Variable(Common):
elif tag == 'check': elif tag == 'check':
self.attrib['validators'].append(self.calculation_value(child, ['ParamSelfOption()'])) self.attrib['validators'].append(self.calculation_value(child, ['ParamSelfOption()']))
elif tag == 'choice': elif tag == 'choice':
choices.append(child.name) if child.type == 'calculation':
value = self.storage.get(child.name).get()
choices = f"Calculation(func.calc_value, Params((ParamOption({value}))))"
else:
choices.append(child.name)
if choices: if choices:
self.attrib['values'] = tuple(choices) if isinstance(choices, list):
self.attrib['values'] = str(tuple(choices))
else:
self.attrib['values'] = choices
if self.attrib['default'] == []: if self.attrib['default'] == []:
del self.attrib['default'] del self.attrib['default']
elif not self.attrib['multi'] and isinstance(self.attrib['default'], list): elif not self.attrib['multi'] and isinstance(self.attrib['default'], list):
@ -387,7 +373,7 @@ class Variable(Common):
function = child.name function = child.name
if hasattr(child, 'param'): if hasattr(child, 'param'):
for param in child.param: for param in child.param:
value = self.populate_param(param) value = self.populate_param(function, param)
if not hasattr(param, 'name'): if not hasattr(param, 'name'):
args.append(str(value)) args.append(str(value))
else: else:
@ -401,6 +387,7 @@ class Variable(Common):
return ret + ')' return ret + ')'
def populate_param(self, def populate_param(self,
function: str,
param, param,
): ):
if param.type == 'string': if param.type == 'string':
@ -410,11 +397,15 @@ class Variable(Common):
elif param.type == 'variable': elif param.type == 'variable':
value = {'option': param.text, value = {'option': param.text,
'notraisepropertyerror': param.notraisepropertyerror, 'notraisepropertyerror': param.notraisepropertyerror,
'todict': param.text in FUNC_TO_DICT, 'todict': function in FUNC_TO_DICT,
} }
if hasattr(param, 'suffix'): if hasattr(param, 'suffix'):
value['suffix'] = param.suffix value['suffix'] = param.suffix
return self.build_param(value) return self.build_param(value)
elif param.type == 'information':
return f'ParamInformation("{param.text}", None)'
elif param.type == 'suffix':
return f'ParamSuffix()'
raise LoaderError(_('unknown param type {}').format(param.type)) raise LoaderError(_('unknown param type {}').format(param.type))
def populate_value(self, def populate_value(self,
@ -429,7 +420,7 @@ class Variable(Common):
self.attrib['default'].append(value) self.attrib['default'].append(value)
if not self.is_leader: if not self.is_leader:
self.attrib['default_multi'] = value self.attrib['default_multi'] = value
elif isinstance(value, int): elif isinstance(value, (int, float)):
self.attrib['default'].append(value) self.attrib['default'].append(value)
else: else:
self.attrib['default'].append("'" + value + "'") self.attrib['default'].append("'" + value + "'")

View File

@ -1,23 +1,19 @@
""" """
utilitaires créole utilitaires créole
""" """
import unicodedata from unicodedata import normalize, combining
from .i18n import _ from .i18n import _
def normalize_family(family_name: str, def valid_name(name: str) -> None:
check_name: bool=True, if '.' in name:
allow_dot: bool=False) -> str: raise ValueError(_(f'"{name}" is a forbidden variable or family name, dot is not allowed'))
def normalize_family(family_name: str) -> str:
"""replace space, accent, uppercase, ... by valid character """replace space, accent, uppercase, ... by valid character
""" """
family_name = family_name.replace('-', '_') family_name = family_name.replace('-', '_').replace(' ', '_').replace('.', '_')
if not allow_dot: nfkd_form = normalize('NFKD', family_name)
family_name = family_name.replace('.', '_') family_name = ''.join([c for c in nfkd_form if not combining(c)])
family_name = family_name.replace(' ', '_') return family_name.lower()
nfkd_form = unicodedata.normalize('NFKD', family_name)
family_name = ''.join([c for c in nfkd_form if not unicodedata.combining(c)])
family_name = family_name.lower()
if check_name and family_name == 'containers':
raise ValueError(_(f'"{family_name}" is a forbidden family name'))
return family_name

View File

@ -1,161 +0,0 @@
try:
import doctest
doctest.OutputChecker
except (AttributeError, ImportError): # Python < 2.4
import util.doctest24 as doctest
try:
import xml.etree.ElementTree as ET
except ImportError:
import elementtree.ElementTree as ET
from xml.parsers.expat import ExpatError as XMLParseError
RealOutputChecker = doctest.OutputChecker
def debug(*msg):
import sys
print >> sys.stderr, ' '.join(map(str, msg))
class HTMLOutputChecker(RealOutputChecker):
def check_output(self, want, got, optionflags):
normal = RealOutputChecker.check_output(self, want, got, optionflags)
if normal or not got:
return normal
try:
want_xml = make_xml(want)
except XMLParseError:
pass
else:
try:
got_xml = make_xml(got)
except XMLParseError:
pass
else:
if xml_compare(want_xml, got_xml):
return True
return False
def output_difference(self, example, got, optionflags):
actual = RealOutputChecker.output_difference(
self, example, got, optionflags)
want_xml = got_xml = None
try:
want_xml = make_xml(example.want)
want_norm = make_string(want_xml)
except XMLParseError as e:
if example.want.startswith('<'):
want_norm = '(bad XML: %s)' % e
# '<xml>%s</xml>' % example.want
else:
return actual
try:
got_xml = make_xml(got)
got_norm = make_string(got_xml)
except XMLParseError as e:
if example.want.startswith('<'):
got_norm = '(bad XML: %s)' % e
else:
return actual
s = '%s\nXML Wanted: %s\nXML Got : %s\n' % (
actual, want_norm, got_norm)
if got_xml and want_xml:
result = []
xml_compare(want_xml, got_xml, result.append)
s += 'Difference report:\n%s\n' % '\n'.join(result)
return s
def xml_sort(children):
tcl1 = {}
#idx = 0
for child in children:
if 'name' in child.attrib:
key = child.attrib['name']
else:
key = child.tag
if key not in tcl1:
tcl1[key] = []
tcl1[key].append(child)
cl1_keys = list(tcl1.keys())
cl1_keys.sort()
cl1 = []
for key in cl1_keys:
cl1.extend(tcl1[key])
return cl1
def xml_compare(x1, x2):
if x1.tag != x2.tag:
print ('Tags do not match: %s and %s' % (x1.tag, x2.tag))
return False
for name, value in x1.attrib.items():
if x2.attrib.get(name) != value:
print ('Attributes do not match: %s=%r, %s=%r'
% (name, value, name, x2.attrib.get(name)))
return False
for name in x2.attrib:
if name not in x1.attrib:
print ('x2 has an attribute x1 is missing: %s'
% name)
return False
if not text_compare(x1.text, x2.text):
print ('text: %r != %r' % (x1.text, x2.text))
return False
if not text_compare(x1.tail, x2.tail):
print ('tail: %r != %r' % (x1.tail, x2.tail))
return False
cl1 = xml_sort(x1.getchildren())
cl2 = xml_sort(x2.getchildren())
if len(cl1) != len(cl2):
cl1_tags = []
for c in cl1:
cl1_tags.append(c.tag)
cl2_tags = []
for c in cl2:
cl2_tags.append(c.tag)
print ('children length differs, %i != %i (%s != %s)'
% (len(cl1), len(cl2), cl1_tags, cl2_tags))
return False
i = 0
for c1, c2 in zip(cl1, cl2):
i += 1
if not xml_compare(c1, c2):
if 'name' in c1.attrib:
name = c1.attrib['name']
else:
name = i
print ('in tag "%s" with name "%s"'
% (c1.tag, name))
return False
return True
def text_compare(t1, t2):
if not t1 and not t2:
return True
if t1 == '*' or t2 == '*':
return True
return (t1 or '').strip() == (t2 or '').strip()
def make_xml(s):
return ET.XML('<xml>%s</xml>' % s)
def make_string(xml):
if isinstance(xml, (str, unicode)):
xml = make_xml(xml)
s = ET.tostring(xml)
if s == '<xml />':
return ''
assert s.startswith('<xml>') and s.endswith('</xml>'), repr(s)
return s[5:-6]
def install():
doctest.OutputChecker = HTMLOutputChecker

View File

@ -37,7 +37,7 @@ class XMLReflector(object):
# document = parse(BytesIO(xmlfile), XMLParser(remove_blank_text=True)) # document = parse(BytesIO(xmlfile), XMLParser(remove_blank_text=True))
document = parse(xmlfile) document = parse(xmlfile)
if not self.dtd.validate(document): if not self.dtd.validate(document):
raise DictConsistencyError(_("not a valid xml file: {}").format(xmlfile)) raise DictConsistencyError(_(f'"{xmlfile}" not a valid xml file: {self.dtd.error_log.filter_from_errors()[0]}'))
return document.getroot() return document.getroot()
def load_xml_from_folders(self, xmlfolders): def load_xml_from_folders(self, xmlfolders):

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_2 = OptionDescription(name='tata', doc='tata', children=[]) option_2 = OptionDescription(name='tata', doc='tata', children=[])
option_2.impl_set_information("manage", True) option_2.impl_set_information("manage", True)
option_1 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_2]) option_1 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_2])

View File

@ -1,6 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True">
@ -10,14 +9,7 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'basic', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'basic', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3, option_4])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True" mode="expert"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True" mode="expert">
@ -12,14 +9,7 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'expert', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'expert', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_4, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,22 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'basic', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'basic', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -1,22 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True" mode="expert"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True" mode="expert">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'expert', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'expert', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'expert'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'expert'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<!-- this is a comment --> <!-- this is a comment -->
@ -10,14 +7,7 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -12,14 +9,7 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_4 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='without_type', doc='without_type', multi=False, default='non') option_4 = StrOption(properties=frozenset({'mandatory', 'normal'}), name='without_type', doc='without_type', multi=False, default='non')
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,22 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -1,22 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,23 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name='général'> <family name='général'>
<variable name='mode_conteneur_actif1' type='oui/non' description="No change" hidden="True"> <variable name='mode_conteneur_actif1' type='oui/non' description="No change" hidden="True">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_4 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -12,7 +9,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -20,9 +16,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -12,16 +9,12 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
<fill name="calc_val" target="mode_conteneur_actif"> <fill name="calc_val" target="mode_conteneur_actif">
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((), kwargs={})), values=('oui', 'non'))
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<services>
<service name="test">
<file name="/etc/file"/>
</service>
</services>
<variables>
<family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="Description">
<value>non</value>
</variable>
</family>
<separators/>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View File

@ -0,0 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "services.test.files.file.group": "root", "services.test.files.file.mode": "0644", "services.test.files.file.name": "/etc/file", "services.test.files.file.owner": "root", "services.test.files.file.source": "file", "services.test.files.file.templating": true, "services.test.files.file.activate": true}

View File

@ -0,0 +1 @@
non

View File

@ -0,0 +1,26 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='Description', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_8 = StrOption(name='group', doc='group', multi=False, default='root')
option_9 = StrOption(name='mode', doc='mode', multi=False, default='0644')
option_10 = StrOption(name='name', doc='name', multi=False, default='/etc/file')
option_11 = StrOption(name='owner', doc='owner', multi=False, default='root')
option_12 = StrOption(name='source', doc='source', multi=False, default='file')
option_13 = BoolOption(name='templating', doc='templating', multi=False, default=True)
option_14 = BoolOption(name='activate', doc='activate', multi=False, default=True)
option_7 = OptionDescription(name='file', doc='file', children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
option_6 = OptionDescription(name='files', doc='files', children=[option_7])
option_5 = OptionDescription(name='test', doc='test', children=[option_6])
option_5.impl_set_information("manage", True)
option_4 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_5])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1, option_4])

View File

@ -0,0 +1 @@
%include "incfile"

View File

@ -0,0 +1 @@
%%mode_conteneur_actif

View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<services>
<service name="test">
<file name="/etc/file"/>
</service>
</services>
<variables>
<family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="Description">
<value>non</value>
</variable>
</family>
<separators/>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View File

@ -0,0 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "services.test.files.file.group": "root", "services.test.files.file.mode": "0644", "services.test.files.file.name": "/etc/file", "services.test.files.file.owner": "root", "services.test.files.file.source": "file", "services.test.files.file.templating": true, "services.test.files.file.activate": true}

View File

@ -0,0 +1,5 @@
--- tmpl/file 2020-11-20 07:44:38.588472784 +0100
+++ dest/file 2020-11-20 07:44:54.588536011 +0100
@@ -1 +1 @@
-unpatched
+patched

View File

@ -0,0 +1 @@
patched

View File

@ -0,0 +1,26 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='Description', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_8 = StrOption(name='group', doc='group', multi=False, default='root')
option_9 = StrOption(name='mode', doc='mode', multi=False, default='0644')
option_10 = StrOption(name='name', doc='name', multi=False, default='/etc/file')
option_11 = StrOption(name='owner', doc='owner', multi=False, default='root')
option_12 = StrOption(name='source', doc='source', multi=False, default='file')
option_13 = BoolOption(name='templating', doc='templating', multi=False, default=True)
option_14 = BoolOption(name='activate', doc='activate', multi=False, default=True)
option_7 = OptionDescription(name='file', doc='file', children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
option_6 = OptionDescription(name='files', doc='files', children=[option_7])
option_5 = OptionDescription(name='test', doc='test', children=[option_6])
option_5.impl_set_information("manage", True)
option_4 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_5])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1, option_4])

View File

@ -0,0 +1 @@
unpatched

View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<services>
<service name="test">
<file name="/etc/systemd-makefs@dev-disk-by\\x2dpartlabel"/>
</service>
</services>
<variables>
<family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="Description">
<value>non</value>
</variable>
</family>
<separators/>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View File

@ -0,0 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.group": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.mode": "0644", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.name": "/etc/systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.owner": "root", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.source": "systemd-makefs@dev-disk-by\\x2dpartlabel", "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.templating": true, "services.test.files.systemd_makefs@dev_disk_by\\x2dpartlabel.activate": true}

View File

@ -0,0 +1,26 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='Description', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_8 = StrOption(name='group', doc='group', multi=False, default='root')
option_9 = StrOption(name='mode', doc='mode', multi=False, default='0644')
option_10 = StrOption(name='name', doc='name', multi=False, default='/etc/systemd-makefs@dev-disk-by\\x2dpartlabel')
option_11 = StrOption(name='owner', doc='owner', multi=False, default='root')
option_12 = StrOption(name='source', doc='source', multi=False, default='systemd-makefs@dev-disk-by\\x2dpartlabel')
option_13 = BoolOption(name='templating', doc='templating', multi=False, default=True)
option_14 = BoolOption(name='activate', doc='activate', multi=False, default=True)
option_7 = OptionDescription(name='systemd_makefs@dev_disk_by\\x2dpartlabel', doc='systemd-makefs@dev-disk-by\\x2dpartlabel', children=[option_8, option_9, option_10, option_11, option_12, option_13, option_14])
option_6 = OptionDescription(name='files', doc='files', children=[option_7])
option_5 = OptionDescription(name='test', doc='test', children=[option_6])
option_5.impl_set_information("manage", True)
option_4 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_5])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1, option_4])

View File

@ -0,0 +1 @@
%%mode_conteneur_actif

View File

@ -0,0 +1,16 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<variables>
<family name="general">
<variable name="float" type="float" description="Description">
<value>0.527</value>
</variable>
<variable name="float_multi" type="float" description="Description" multi="True">
<value>0.527</value>
</variable>
</family>
<separators/>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View File

@ -0,0 +1 @@
{"rougail.general.float": 0.527, "rougail.general.float_multi": [0.527]}

View File

@ -0,0 +1,15 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = FloatOption(properties=frozenset({'mandatory', 'normal'}), name='float', doc='Description', multi=False, default=0.527)
option_4 = FloatOption(properties=frozenset({'mandatory', 'normal'}), name='float_multi', doc='Description', multi=True, default=[0.527], default_multi=0.527)
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])

View File

@ -1,22 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="Redefine description" hidden="True" multi="True"> <variable name="mode_conteneur_actif" type="oui/non" description="Redefine description" hidden="True" multi="True">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='Redefine description', multi=True, default=['non'], default_multi='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='Redefine description', multi=True, default=['non'], default_multi='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -0,0 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?>
<rougail>
<variables>
<family name="general">
<variable name="general" type="oui/non" description="description">
<value>non</value>
</variable>
</family>
</variables>
</rougail>
<!-- vim: ts=4 sw=4 expandtab
-->

View File

@ -0,0 +1 @@
{"rougail.general.general": "non"}

View File

@ -0,0 +1,14 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try:
from tiramisu3 import *
except:
from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription
option_3 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='general', doc='description', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True">
@ -15,7 +12,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -23,9 +19,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non", "rougail.general.module_instancie": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non", "rougail.general.module_instancie": "non"}

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_5 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non')) option_5 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='module_instancie', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'basic', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_5, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'auto_freeze', 'basic', 'force_store_value', 'mandatory', Calculation(calc_value, Params(ParamValue('auto_frozen'), kwargs={'condition': ParamOption(option_5, todict=True), 'expected': ParamValue('oui'), 'reverse_condition': ParamValue(True)}))}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_save="True">
@ -12,7 +9,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -20,9 +16,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'basic', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'basic', 'force_store_value', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'basic'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'basic'}), children=[option_3, option_4])

View File

@ -1,18 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change"/>
<value>non</value>
</variable>
<variable name="mode_conteneur_actif1" type="oui/non" description="No change"> <variable name="mode_conteneur_actif1" type="oui/non" description="No change">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -20,9 +14,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,12 +1,15 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="Général"> <family name="Général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -12,7 +9,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -20,9 +16,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='Général', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='Général', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,16 +1,12 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general" mode="basic"> <family name="general" mode="basic">
<variable name="mode_conteneur_actif" type="domain" description="No change" mandatory="True" mode="expert"/> <variable name="mode_conteneur_actif" type="oui/non" description="No change" mandatory="True" mode="expert"/>
<variable name="mode_conteneur_actif1" type="oui/non" description="No change"> <variable name="mode_conteneur_actif1" type="oui/non" description="No change">
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -18,9 +14,6 @@
<param type="variable">mode_conteneur_actif1</param> <param type="variable">mode_conteneur_actif1</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,12 +1,15 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = DomainnameOption(type='domainname', allow_ip=False, properties=frozenset({'expert', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={}))) option_3 = ChoiceOption(properties=frozenset({'expert', 'mandatory'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="number" description="No change" hidden="True"/> <variable name="mode_conteneur_actif" type="number" description="No change" hidden="True"/>
@ -10,7 +7,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -18,9 +14,6 @@
<param type="number">3</param> <param type="number">3</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": 3, "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,11 +1,14 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp option_3 = IntOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamValue(3)), kwargs={})))
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = IntOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamValue(3)), kwargs={})))
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -12,7 +9,6 @@
<value>non</value> <value>non</value>
</variable> </variable>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
@ -22,9 +18,6 @@
<param type="variable" optional="True">mode_conteneur_actif3</param> <param type="variable" optional="True">mode_conteneur_actif3</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non')) option_4 = ChoiceOption(properties=frozenset({'mandatory', 'normal'}), name='mode_conteneur_actif1', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default=Calculation(func.calc_val, Params((ParamOption(option_4, notraisepropertyerror=False, todict=False)), kwargs={})), values=('oui', 'non'))
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3, option_4])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -13,12 +10,6 @@
<separator name="mode_conteneur_actif">Établissement</separator> <separator name="mode_conteneur_actif">Établissement</separator>
</separators> </separators>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3.impl_set_information("separator", "Établissement") option_3.impl_set_information("separator", "Établissement")
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="general"> <family name="general">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -13,12 +10,6 @@
<separator name="mode_conteneur_actif">Établissement</separator> <separator name="mode_conteneur_actif">Établissement</separator>
</separators> </separators>
</variables> </variables>
<constraints>
</constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1,10 +1,13 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_3.impl_set_information("separator", "Établissement") option_3.impl_set_information("separator", "Établissement")
option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3]) option_2 = OptionDescription(name='general', doc='general', properties=frozenset({'normal'}), children=[option_3])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -10,18 +7,13 @@
</variable> </variable>
<variable name="autosavevar" type="string" description="autosave variable" hidden="True" auto_save="True"/> <variable name="autosavevar" type="string" description="autosave variable" hidden="True" auto_save="True"/>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
<fill name="calc_val" target="autosavevar"> <fill name="calc_val" target="autosavevar">
<param>oui</param> <param>oui</param>
</fill> </fill>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

View File

@ -1 +1 @@
{"rougail.general.mode_conteneur_actif": "non", "rougail.general.autosavevar": null} {"rougail.general.mode_conteneur_actif": "non", "rougail.general.autosavevar": "oui"}

View File

@ -1,12 +1,15 @@
from importlib.machinery import SourceFileLoader
func = SourceFileLoader('func', 'tests/dictionaries/../eosfunc/test.py').load_module()
for key, value in dict(locals()).items():
if key != ['SourceFileLoader', 'func']:
setattr(func, key, value)
try: try:
from tiramisu3 import * from tiramisu3 import *
except: except:
from tiramisu import * from tiramisu import *
from rougail.tiramisu import ConvertDynOptionDescription from rougail.tiramisu import ConvertDynOptionDescription
import imp
func = imp.load_source('func', 'tests/dictionaries/../eosfunc/test.py')
option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non')) option_3 = ChoiceOption(properties=frozenset({'force_default_on_freeze', 'frozen', 'hidden', 'mandatory', 'normal'}), name='mode_conteneur_actif', doc='No change', multi=False, default='non', values=('oui', 'non'))
option_4 = StrOption(properties=frozenset({'basic', 'force_store_value', 'frozen', 'hidden', 'mandatory'}), name='autosavevar', doc='autosave variable', multi=False, default=Calculation(func.calc_val, Params((ParamValue("oui")), kwargs={}))) option_4 = StrOption(properties=frozenset({'basic', 'force_store_value', 'frozen', 'hidden'}), name='autosavevar', doc='autosave variable', multi=False, default=Calculation(func.calc_val, Params((ParamValue("oui")), kwargs={})))
option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3, option_4]) option_2 = OptionDescription(name='general', doc='général', properties=frozenset({'basic'}), children=[option_3, option_4])
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2]) option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1]) option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])

View File

@ -1,8 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<rougail> <rougail>
<services/>
<variables> <variables>
<family name="général"> <family name="général">
<variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True"> <variable name="mode_conteneur_actif" type="oui/non" description="No change" hidden="True">
@ -10,7 +7,6 @@
</variable> </variable>
<variable name="autosavevar" type="string" description="autosave variable" auto_save="True"/> <variable name="autosavevar" type="string" description="autosave variable" auto_save="True"/>
</family> </family>
<separators/>
</variables> </variables>
<constraints> <constraints>
<fill name="calc_val" target="autosavevar"> <fill name="calc_val" target="autosavevar">
@ -20,11 +16,7 @@
<param>oui</param> <param>oui</param>
<target type="variable">autosavevar</target> <target type="variable">autosavevar</target>
</condition> </condition>
</constraints> </constraints>
<help/>
</rougail> </rougail>
<!-- vim: ts=4 sw=4 expandtab <!-- vim: ts=4 sw=4 expandtab
--> -->

Some files were not shown because too many files have changed in this diff Show More