add fill/auto with dynamic option

This commit is contained in:
Emmanuel Garette 2020-04-11 20:45:28 +02:00
parent b0b44d4ee1
commit 1cd8873e5b
6 changed files with 118 additions and 17 deletions

View file

@ -237,6 +237,7 @@ class ServiceAnnotator:
self.paths.add_variable('services', self.paths.add_variable('services',
path, path,
'service', 'service',
False,
variable, variable,
) )
return variable return variable
@ -1116,7 +1117,11 @@ class SpaceAnnotator(object):
# if param.optional is True: # if param.optional is True:
# param_option_indexes.append(fill_idx) # param_option_indexes.append(fill_idx)
try: try:
param.text = self.paths.get_variable_path(param.text, namespace) param.text, suffix = self.paths.get_variable_path(param.text,
namespace,
with_suffix=True)
if suffix:
param.suffix = suffix
except CreoleDictConsistencyError as err: except CreoleDictConsistencyError as err:
if param.optional is True: if param.optional is True:
param_option_indexes.append(fill_idx) param_option_indexes.append(fill_idx)

View file

@ -11,7 +11,7 @@ from tiramisu import (StrOption, OptionDescription, DynOptionDescription, PortOp
NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption, NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption,
URLOption, EmailOption, FilenameOption, UsernameOption, DateOption, URLOption, EmailOption, FilenameOption, UsernameOption, DateOption,
PasswordOption, BoolOption, MACOption, Leadership, submulti, PasswordOption, BoolOption, MACOption, Leadership, submulti,
Params, ParamSelfOption, ParamOption, ParamValue, Calculation, calc_value, Params, ParamSelfOption, ParamOption, ParamDynOption, ParamValue, Calculation, calc_value,
groups, owners) groups, owners)
from tiramisu.error import ConfigError from tiramisu.error import ConfigError
@ -431,7 +431,7 @@ class Variable(Common):
transitive = False transitive = False
else: else:
raise CreoleLoaderError(_('unknown transitive boolean {}').format(transitive)) raise CreoleLoaderError(_('unknown transitive boolean {}').format(transitive))
value = [param.text, transitive] value = [param.text, transitive, param.attrib.get('suffix')]
elif param.attrib['type'] == 'number': elif param.attrib['type'] == 'number':
value = int(param.text) value = int(param.text)
else: else:
@ -462,10 +462,21 @@ class Variable(Common):
if len(value) == 3: if len(value) == 3:
for param in value[1]: for param in value[1]:
if isinstance(param[1], list): if isinstance(param[1], list):
option = self.storage.get(param[1][0]).get()
param_kwargs = {'notraisepropertyerror': param[1][1]}
if value[0] in FUNC_TO_DICT: if value[0] in FUNC_TO_DICT:
param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1], todict=True) param_kwargs['todict'] = True
if not param[1][2]:
param_value = ParamOption(option,
**param_kwargs,
)
else: else:
param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1]) family = '.'.join(param[1][0].split('.', 3)[:2])
param_value = ParamDynOption(option,
param[1][2],
self.storage.get(family).get(),
**param_kwargs,
)
else: else:
param_value = ParamValue(param[1]) param_value = ParamValue(param[1])
if not param[0]: if not param[0]:

View file

@ -197,6 +197,7 @@ class CreoleObjSpace(object):
self.paths.add_variable(namespace, self.paths.add_variable(namespace,
name, name,
family.name, family.name,
False,
variable_obj, variable_obj,
) )
return variable_obj return variable_obj
@ -423,7 +424,13 @@ class CreoleObjSpace(object):
if list(child) != []: if list(child) != []:
self.xml_parse_document(child, creoleobj, namespace, is_in_family) self.xml_parse_document(child, creoleobj, namespace, is_in_family)
def _fill_creoleobj_path_attribute(self, space, child, namespace, document, creoleobj): # pylint: disable=R0913 def _fill_creoleobj_path_attribute(self,
space,
child,
namespace,
document,
creoleobj,
): # pylint: disable=R0913
"""Fill self.paths attributes """Fill self.paths attributes
""" """
if not isinstance(space, self.help): # pylint: disable=E1101 if not isinstance(space, self.help): # pylint: disable=E1101
@ -432,6 +439,7 @@ class CreoleObjSpace(object):
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,
creoleobj) creoleobj)
if child.attrib.get('redefine', 'False') == 'True': if child.attrib.get('redefine', 'False') == 'True':
if namespace == 'creole': if namespace == 'creole':
@ -655,8 +663,10 @@ class Path:
new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name
self.add_variable(namespace, self.add_variable(namespace,
new_path, new_path,
family=dico['family'], dico['family'],
creoleobj=dico['creoleobj']) False,
dico['creoleobj'],
)
name = new_path name = new_path
dico = self._get_variable(name) dico = self._get_variable(name)
if dico['leader'] != None: if dico['leader'] != None:
@ -671,8 +681,9 @@ class Path:
def add_variable(self, def add_variable(self,
namespace: str, namespace: str,
name: str, name: str,
family: str=None, family: str,
creoleobj=None, is_dynamic: bool,
creoleobj,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if namespace == 'creole' or '.' in name: if namespace == 'creole' or '.' in name:
varname = name varname = name
@ -682,6 +693,7 @@ class Path:
family=family, family=family,
namespace=namespace, namespace=namespace,
leader=None, leader=None,
is_dynamic=is_dynamic,
creoleobj=creoleobj) creoleobj=creoleobj)
def get_variable_name(self, def get_variable_name(self,
@ -717,22 +729,32 @@ class Path:
name: str, name: str,
current_namespace: str, current_namespace: str,
allow_source: str=False, allow_source: str=False,
with_suffix: bool=False,
) -> str: # pylint: disable=C0111 ) -> str: # pylint: disable=C0111
if current_namespace is None: # pragma: no cover if current_namespace is None: # pragma: no cover
raise CreoleOperationError('current_namespace must not be None') raise CreoleOperationError('current_namespace must not be None')
dico = self._get_variable(name) if with_suffix:
dico, suffix = self._get_variable(name,
with_suffix=True,
)
else:
dico = self._get_variable(name)
if not allow_source: if not allow_source:
if dico['namespace'] not in ['creole', 'services'] and current_namespace != dico['namespace']: if dico['namespace'] not in ['creole', 'services'] and current_namespace != dico['namespace']:
raise CreoleDictConsistencyError(_('A variable located in the {} namespace ' raise CreoleDictConsistencyError(_('A variable located in the {} namespace '
'shall not be used in the {} namespace').format( 'shall not be used in the {} namespace').format(
dico['namespace'], current_namespace)) dico['namespace'], current_namespace))
if '.' in dico['name']: if '.' in dico['name']:
return dico['name'] value = dico['name']
list_path = [dico['namespace'], dico['family']] else:
if dico['leader'] is not None: list_path = [dico['namespace'], dico['family']]
list_path.append(dico['leader']) if dico['leader'] is not None:
list_path.append(dico['name']) list_path.append(dico['leader'])
return '.'.join(list_path) list_path.append(dico['name'])
value = '.'.join(list_path)
if with_suffix:
return value, suffix
return value
def path_is_defined(self, def path_is_defined(self,
name: str, name: str,
@ -741,10 +763,16 @@ class Path:
def _get_variable(self, def _get_variable(self,
name: str, name: str,
with_suffix: bool=False,
) -> str: ) -> str:
if name not in self.variables: if name not in self.variables:
if name.startswith('creole.'): if name.startswith('creole.'):
name = name.split('.')[-1] name = name.split('.')[-1]
if name not in self.variables: if name not in self.variables:
for var_name, variable in self.variables.items():
if variable['is_dynamic'] and name.startswith(var_name):
return variable, name[len(var_name):]
raise CreoleDictConsistencyError(_('unknown option {}').format(name)) raise CreoleDictConsistencyError(_('unknown option {}').format(name))
if with_suffix:
return self.variables[name], None
return self.variables[name] return self.variables[name]

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<rougail>
<variables>
<family name='general'>
<variable name='varname' type='string' description="No change" multi="True">
<value>val1</value>
<value>val2</value>
</variable>
</family>
<family name='dyn' dynamic="varname">
<variable name='vardyn' type='string' description="No change">
<value>val</value>
</variable>
</family>
<family name='new'>
<variable name='newvar' type='string' description="No change"/>
</family>
</variables>
<constraints>
<fill name="calc_val" target="newvar">
<param type="variable">vardynval1</param>
</fill>
</constraints>
</rougail>

View file

@ -0,0 +1 @@
{"creole.general.varname": ["val1", "val2"], "creole.dynval1.vardynval1": "val", "creole.dynval2.vardynval2": "val", "creole.new.newvar": null}

View file

@ -0,0 +1,31 @@
<?xml version='1.0' encoding='UTF-8'?>
<creole>
<family doc="" name="creole">
<family doc="general" name="general">
<property>normal</property>
<variable doc="No change" multi="True" name="varname" type="string">
<property>mandatory</property>
<property>normal</property>
<value>val1</value>
<value>val2</value>
</variable>
</family>
<family dynamic="creole.general.varname" doc="dyn" name="dyn">
<property>normal</property>
<variable doc="No change" multi="False" name="vardyn" type="string">
<property>mandatory</property>
<property>normal</property>
<value>val</value>
</variable>
</family>
<family doc="new" name="new">
<property>normal</property>
<variable doc="No change" multi="False" name="newvar" type="string">
<property>normal</property>
<value name="calc_val" type="calculation">
<param suffix="val1" transitive="False" type="variable">creole.dyn.vardyn</param>
</value>
</variable>
</family>
</family>
</creole>