diff --git a/data/creole.dtd b/data/creole.dtd
index 95cd2d45..1b5e96f5 100644
--- a/data/creole.dtd
+++ b/data/creole.dtd
@@ -149,6 +149,7 @@
+
@@ -166,6 +167,7 @@
+
diff --git a/src/rougail/annotator.py b/src/rougail/annotator.py
index 2d924f63..984aa3cf 100644
--- a/src/rougail/annotator.py
+++ b/src/rougail/annotator.py
@@ -266,8 +266,12 @@ class ContainerAnnotator:
disknod.permission = 'allow'
def _update_file(self, file_, index, container_path):
- if not hasattr(file_, 'source'):
- file_.source = basename(file_.name)
+ if file_.name_type == "UnicodeOption":
+ if not hasattr(file_, 'source'):
+ file_.source = basename(file_.name)
+ elif not hasattr(file_, 'source'):
+ raise CreoleDictConsistencyError(_('attribute source mandatory for file with SymLinkOption name '
+ 'for {}').format(file_.name))
def _split_elts(self, name, key, value, elt):
"""for example::
@@ -483,6 +487,7 @@ class SpaceAnnotator(object):
self.remove_empty_families()
self.change_variable_mode()
self.change_family_mode()
+ self.dynamic_families()
self.filter_separators()
self.absolute_path_for_symlink_in_containers()
self.convert_helps()
@@ -611,6 +616,17 @@ class SpaceAnnotator(object):
else:
family.mode = mode
+ def dynamic_families(self): # pylint: disable=C0111
+ if not hasattr(self.space, 'variables'):
+ return
+ for family in self.space.variables.values():
+ if hasattr(family, 'family'):
+ for family in family.family.values():
+ if 'dynamic' in vars(family):
+ namespace = self.paths.get_variable_namespace(family.dynamic)
+ varpath = self.paths.get_variable_path(family.dynamic, namespace)
+ family.dynamic = varpath
+
def _annotate_variable(self, variable, family_mode, path, is_follower=False):
if (HIGH_COMPATIBILITY and variable.type == 'choice' and variable.mode != modes_level[-1] and variable.mandatory is True and path in self.default_has_no_value):
variable.mode = modes_level[0]
diff --git a/src/rougail/loader.py b/src/rougail/loader.py
index 27e16597..72509492 100644
--- a/src/rougail/loader.py
+++ b/src/rougail/loader.py
@@ -6,7 +6,7 @@ from os import listdir
#from ast import literal_eval
from lxml.etree import parse, DTD
-from tiramisu.option import (StrOption, OptionDescription, PortOption,
+from tiramisu.option import (StrOption, OptionDescription, DynOptionDescription, PortOption,
IntOption, ChoiceOption, BoolOption, SymLinkOption, IPOption,
NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption,
URLOption, EmailOption, FilenameOption, UsernameOption, DateOption,
@@ -117,9 +117,9 @@ class PopulateTiramisuObjects(object):
def make_tiramisu_objects(self, xmlroot, creolefunc_file):
elt = Elt({'name': 'baseoption'})
- family = Family(elt, self.booleans, self.storage)
- self.storage.add('.', family)
self.eosfunc = imp.load_source('eosfunc', creolefunc_file)
+ family = Family(elt, self.booleans, self.storage, self.eosfunc)
+ self.storage.add('.', family)
elts = {}
for elt in xmlroot:
@@ -167,7 +167,7 @@ class PopulateTiramisuObjects(object):
force_icon = False
else:
force_icon = not subpath.startswith('containers') and not subpath.startswith('actions')
- family = Family(elt, self.booleans, self.storage, force_icon)
+ family = Family(elt, self.booleans, self.storage, self.eosfunc, force_icon)
path = self._build_path(subpath, elt)
self.storage.add(path, family)
return family
@@ -181,7 +181,7 @@ class PopulateTiramisuObjects(object):
def _iter_leader(self, leader, subpath):
subpath = self._build_path(subpath, leader)
- family = Family(leader, self.booleans, self.storage)
+ family = Family(leader, self.booleans, self.storage, self.eosfunc)
family.set_leader()
self.storage.add(subpath, family)
leader_name = None
@@ -474,7 +474,7 @@ class Variable(Common):
class Family(Common):
- def __init__(self, elt, booleans, storage, force_icon=False):
+ def __init__(self, elt, booleans, storage, eosfunc, force_icon=False):
self.option = None
self.attrib = {}
self.is_leader = False
@@ -484,6 +484,7 @@ class Family(Common):
self.informations = {}
self.children = []
self.storage = storage
+ self.eosfunc = eosfunc
self.attrib['properties'] = []
for key, value in elt.attrib.items():
if key in booleans:
@@ -528,11 +529,16 @@ class Family(Common):
self.attrib['children'].append(child.get())
self.build_properties()
try:
- if not self.is_leader:
+ if 'dynamic' in self.attrib:
+ dynamic = self.storage.get(self.attrib['dynamic']).get()
+ del self.attrib['dynamic']
+ self.attrib['suffixes'] = Calculation(self.eosfunc.calc_value,
+ Params((ParamOption(dynamic),)))
+ option = DynOptionDescription(**self.attrib)
+ elif not self.is_leader:
option = OptionDescription(**self.attrib)
else:
option = Leadership(**self.attrib)
- #option = OptionDescription(**self.attrib)
except Exception as err:
raise CreoleLoaderError(_('cannot create optiondescription {}: {}').format(self.attrib['name'], err))
for key, value in self.informations.items():
diff --git a/tests/eosfunc/test.py b/tests/eosfunc/test.py
index 9aefc582..638625f1 100644
--- a/tests/eosfunc/test.py
+++ b/tests/eosfunc/test.py
@@ -1,4 +1,4 @@
-from tiramisu import valid_not_equal, valid_ip_netmask
+from tiramisu import valid_not_equal, valid_ip_netmask, calc_value
def calc_val(*args, **kwargs):
pass
diff --git a/tests/flattener_dicos/20family_dynamic/00-base.xml b/tests/flattener_dicos/20family_dynamic/00-base.xml
new file mode 100644
index 00000000..26c61f0c
--- /dev/null
+++ b/tests/flattener_dicos/20family_dynamic/00-base.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ val1
+ val2
+
+
+
+
+
+
+
diff --git a/tests/flattener_dicos/20family_dynamic/makedict/base.json b/tests/flattener_dicos/20family_dynamic/makedict/base.json
new file mode 100644
index 00000000..64870f69
--- /dev/null
+++ b/tests/flattener_dicos/20family_dynamic/makedict/base.json
@@ -0,0 +1 @@
+{"creole.general.varname": ["val1", "val2"], "creole.dynval1.vardynval1": null, "creole.dynval2.vardynval2": null}
\ No newline at end of file
diff --git a/tests/flattener_dicos/20family_dynamic/result/00-base.xml b/tests/flattener_dicos/20family_dynamic/result/00-base.xml
new file mode 100644
index 00000000..cc55d6ca
--- /dev/null
+++ b/tests/flattener_dicos/20family_dynamic/result/00-base.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ normal
+
+ mandatory
+ normal
+ val1
+ val2
+
+
+
+ normal
+
+ normal
+
+
+
+
diff --git a/tests/flattener_dicos/70container_files_symlink_multi/00-base.xml b/tests/flattener_dicos/70container_files_symlink_multi/00-base.xml
new file mode 100644
index 00000000..0b49c3b0
--- /dev/null
+++ b/tests/flattener_dicos/70container_files_symlink_multi/00-base.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+ oui
+
+
+ /etc/mailname
+ /etc/mailname2
+
+
+
+
+
diff --git a/tests/flattener_dicos/70container_files_symlink_multi/makedict/base.json b/tests/flattener_dicos/70container_files_symlink_multi/makedict/base.json
new file mode 100644
index 00000000..e5344ac6
--- /dev/null
+++ b/tests/flattener_dicos/70container_files_symlink_multi/makedict/base.json
@@ -0,0 +1 @@
+{"creole.general.file_name": ["/etc/mailname", "/etc/mailname2"], "containers.container0.files.file0.mkdir": false, "containers.container0.files.file0.name": ["/etc/mailname", "/etc/mailname2"], "containers.container0.files.file0.rm": false, "containers.container0.files.file0.source": "mailname", "containers.container0.files.file0.activate": true}
\ No newline at end of file
diff --git a/tests/flattener_dicos/70container_files_symlink_multi/result/00-base.xml b/tests/flattener_dicos/70container_files_symlink_multi/result/00-base.xml
new file mode 100644
index 00000000..ed1f4463
--- /dev/null
+++ b/tests/flattener_dicos/70container_files_symlink_multi/result/00-base.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+ False
+
+
+
+ False
+
+
+ mailname
+
+
+ True
+
+
+
+ basic
+
+
+
+
+ normal
+
+ oui
+ non
+ force_default_on_freeze
+ frozen
+ hidden
+ mandatory
+ normal
+ oui
+
+
+ mandatory
+ normal
+ /etc/mailname
+ /etc/mailname2
+
+
+
+
+
diff --git a/tests/flattener_dicos/80container_files_symlink_without_source/00-base.xml b/tests/flattener_dicos/80container_files_symlink_without_source/00-base.xml
new file mode 100644
index 00000000..62986e0a
--- /dev/null
+++ b/tests/flattener_dicos/80container_files_symlink_without_source/00-base.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+ oui
+
+
+ /etc/mailname
+
+
+
+
+
diff --git a/tests/test_flattener.py b/tests/test_flattener.py
index 6031de0b..284ece34 100644
--- a/tests/test_flattener.py
+++ b/tests/test_flattener.py
@@ -4,11 +4,9 @@ from pytest import fixture, raises
from os import listdir
from json import load
-#from creole.xmlreflector import CreoleObjSpace, CreoleDictConsistencyError
-#from creole import xmlreflector
from rougail import objspace, annotator
-from creole.xml_compare import xml_compare
-from creole.error import CreoleDictConsistencyError
+from rougail.xml_compare import xml_compare
+from rougail.error import CreoleDictConsistencyError
from rougail.config import dtdfilename
@@ -85,7 +83,7 @@ def launch_flattener(test_dir):
eolobj.save(destfile)
result_file = join(test_dir, 'result/00-base.xml')
if isfile(result_file):
-# eolobj.save(result_file)
+ # eolobj.save(result_file)
compare_xml(destfile, result_file)
diff --git a/tests/test_makedict.py b/tests/test_makedict.py
index a22af6aa..7d410d62 100644
--- a/tests/test_makedict.py
+++ b/tests/test_makedict.py
@@ -24,7 +24,7 @@ for test in listdir(dico_dirs):
excludes = set([])
excludes = set([])
test_ok -= excludes
-#test_ok = ['70container_all']
+#test_ok = ['20family_dynamic']
test_ok = list(test_ok)
diff --git a/tests/test_template.py b/tests/test_template.py
index 2b5c844d..576e6be8 100644
--- a/tests/test_template.py
+++ b/tests/test_template.py
@@ -22,13 +22,11 @@ def test_dictionary(test_dir):
test_dir = join(template_dirs, test_dir)
tmp_dir = join(test_dir, 'tmp')
funcs_file = join(template_dirs, '../eosfunc/test.py')
- template.distrib_dir = join(test_dir, 'tmpl')
- template.templatedir = tmp_dir
+ distrib_dir = join(test_dir, 'tmpl')
if isdir(tmp_dir):
rmtree(tmp_dir)
mkdir(tmp_dir)
dest_dir = join(test_dir, 'dest')
- template.dest_dir = dest_dir
if isdir(dest_dir):
rmtree(dest_dir)
mkdir(dest_dir)
@@ -41,13 +39,19 @@ def test_dictionary(test_dir):
config = Config(optiondescription)
config.property.read_only()
template.generate(config,
- funcs_file)
+ funcs_file,
+ distrib_dir,
+ tmp_dir,
+ dest_dir)
- list_templates = set(listdir(dest_dir))
+ if isdir(join(dest_dir, 'test')):
+ list_templates = set(listdir(join(dest_dir, 'test')))
+ else:
+ list_templates = set()
list_results = set(listdir(join(test_dir, 'result')))
assert list_templates == list_results
for result in listdir(join(test_dir, 'result')):
- template_file = join(dest_dir, result)
+ template_file = join(dest_dir, 'test', result)
if not isfile(template_file):
raise Exception(f'{template_file} is not generated')
with open(join(test_dir, 'result', result), 'r') as fh: