Merge branch 'master' into develop
This commit is contained in:
commit
f65e772b39
1055 changed files with 5726 additions and 10797 deletions
|
@ -1,5 +1,5 @@
|
||||||
from .loader import load
|
#from .loader import load
|
||||||
from .objspace import CreoleObjSpace
|
from .objspace import CreoleObjSpace
|
||||||
from .annotator import modes
|
from .annotator import modes
|
||||||
|
|
||||||
__ALL__ = ('load', 'CreoleObjSpace', 'modes')
|
__ALL__ = ('CreoleObjSpace', 'modes')
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,3 +15,5 @@ dtdfilename = join(dtddir, 'rougail.dtd')
|
||||||
|
|
||||||
# chemin du répertoire source des fichiers templates
|
# chemin du répertoire source des fichiers templates
|
||||||
patch_dir = '/srv/rougail/patch'
|
patch_dir = '/srv/rougail/patch'
|
||||||
|
|
||||||
|
variable_namespace = 'rougail'
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
# Forked by:
|
# Forked by:
|
||||||
# Cadoles (http://www.cadoles.com)
|
# Cadoles (http://www.cadoles.com)
|
||||||
# Copyright (C) 2019
|
# Copyright (C) 2019-2020
|
||||||
|
|
||||||
# distribued with GPL-2 or later license
|
# distribued with GPL-2 or later license
|
||||||
|
|
||||||
|
@ -37,54 +37,23 @@
|
||||||
<!-- root element -->
|
<!-- root element -->
|
||||||
<!-- =============== -->
|
<!-- =============== -->
|
||||||
|
|
||||||
<!ELEMENT rougail (services | family_action | variables | constraints | help)*>
|
<!ELEMENT rougail (services | variables | constraints | help)*>
|
||||||
|
|
||||||
<!-- ============== -->
|
<!-- ============== -->
|
||||||
<!-- files element -->
|
<!-- files element -->
|
||||||
<!-- ============== -->
|
<!-- ============== -->
|
||||||
|
|
||||||
<!ELEMENT family_action (action)>
|
|
||||||
<!ATTLIST family_action name CDATA #REQUIRED>
|
|
||||||
<!ATTLIST family_action description CDATA #IMPLIED>
|
|
||||||
<!ATTLIST family_action color CDATA #IMPLIED>
|
|
||||||
<!ATTLIST family_action image CDATA #IMPLIED>
|
|
||||||
<!ELEMENT action ((input* | profile* | ewtapp* | tag* | saltaction*)*)>
|
|
||||||
<!ATTLIST action type (form|custom|external|reader|apache) "custom">
|
|
||||||
<!ATTLIST action title CDATA #REQUIRED>
|
|
||||||
<!ATTLIST action description CDATA #REQUIRED>
|
|
||||||
<!ATTLIST action rewrite CDATA #IMPLIED>
|
|
||||||
<!ATTLIST action image CDATA #IMPLIED>
|
|
||||||
<!ATTLIST action actionlist CDATA #IMPLIED>
|
|
||||||
<!-- for apache action -->
|
|
||||||
<!ATTLIST action apache_path CDATA #IMPLIED>
|
|
||||||
<!ATTLIST action apache_path_type (FilenameOption|SymLinkOption|variable) "FilenameOption">
|
|
||||||
<!-- for external action -->
|
|
||||||
<!ATTLIST action url CDATA #IMPLIED>
|
|
||||||
<!ATTLIST action url_type (URLOption|SymLinkOption|variable) "URLOption">
|
|
||||||
<!-- for form action -->
|
|
||||||
<!ATTLIST action save (True|False) "False">
|
|
||||||
|
|
||||||
<!ELEMENT services (service*)>
|
<!ELEMENT services (service*)>
|
||||||
|
|
||||||
<!ELEMENT service ((port* | tcpwrapper* | ip* | interface* | package* | file* | digitalcertificate*)*) >
|
<!ELEMENT service ((port* | tcpwrapper* | ip* | interface* | package* | file* | digitalcertificate* | override*)*) >
|
||||||
<!ATTLIST service name CDATA #REQUIRED>
|
<!ATTLIST service name CDATA #REQUIRED>
|
||||||
<!ATTLIST service method (systemd|upstart|apache|network) "systemd">
|
<!ATTLIST service manage (True|False) "True">
|
||||||
|
|
||||||
<!ELEMENT input (#PCDATA)>
|
|
||||||
<!ELEMENT profile (#PCDATA)>
|
|
||||||
<!ELEMENT ewtapp (#PCDATA)>
|
|
||||||
<!ELEMENT tag (#PCDATA)>
|
|
||||||
<!ELEMENT saltaction (#PCDATA)>
|
|
||||||
|
|
||||||
<!ELEMENT port (#PCDATA)>
|
<!ELEMENT port (#PCDATA)>
|
||||||
<!ATTLIST port port_type (PortOption|SymLinkOption|variable) "PortOption">
|
<!ATTLIST port port_type (PortOption|SymLinkOption|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 tcpwrapper (#PCDATA)>
|
|
||||||
<!ATTLIST tcpwrapper tcpwrapper_type (UnicodeOption|SymLinkOption|variable) "UnicodeOption">
|
|
||||||
<!ATTLIST tcpwrapper tcpwrapperlist CDATA #IMPLIED >
|
|
||||||
|
|
||||||
<!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|SymLinkOption|variable) "NetworkOption">
|
||||||
|
@ -93,9 +62,6 @@
|
||||||
<!ATTLIST ip netmask_type (NetmaskOption|SymLinkOption|variable) "NetmaskOption">
|
<!ATTLIST ip netmask_type (NetmaskOption|SymLinkOption|variable) "NetmaskOption">
|
||||||
<!ATTLIST ip netmask CDATA "255.255.255.255">
|
<!ATTLIST ip netmask CDATA "255.255.255.255">
|
||||||
|
|
||||||
<!ELEMENT package (#PCDATA)>
|
|
||||||
<!ATTLIST package packagelist CDATA #IMPLIED >
|
|
||||||
|
|
||||||
<!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|SymLinkOption|variable) "UnicodeOption">
|
||||||
|
@ -106,9 +72,8 @@
|
||||||
<!ATTLIST file owner CDATA "root">
|
<!ATTLIST file owner CDATA "root">
|
||||||
<!ATTLIST file group CDATA "root">
|
<!ATTLIST file group CDATA "root">
|
||||||
<!ATTLIST file filelist CDATA #IMPLIED >
|
<!ATTLIST file filelist CDATA #IMPLIED >
|
||||||
<!ATTLIST file mkdir (True|False) "False">
|
|
||||||
<!ATTLIST file rm (True|False) "False">
|
|
||||||
<!ATTLIST file redefine (True|False) "False">
|
<!ATTLIST file redefine (True|False) "False">
|
||||||
|
<!ATTLIST file templating (True|False) "True">
|
||||||
|
|
||||||
<!ELEMENT digitalcertificate EMPTY>
|
<!ELEMENT digitalcertificate EMPTY>
|
||||||
<!ATTLIST digitalcertificate name CDATA #REQUIRED >
|
<!ATTLIST digitalcertificate name CDATA #REQUIRED >
|
||||||
|
@ -118,12 +83,15 @@
|
||||||
<!ATTLIST digitalcertificate type CDATA #REQUIRED >
|
<!ATTLIST digitalcertificate type CDATA #REQUIRED >
|
||||||
<!ATTLIST digitalcertificate ca CDATA #REQUIRED >
|
<!ATTLIST digitalcertificate ca CDATA #REQUIRED >
|
||||||
|
|
||||||
|
<!ELEMENT override EMPTY>
|
||||||
|
<!ATTLIST override source CDATA #IMPLIED >
|
||||||
|
<!ATTLIST override templating (True|False) "True">
|
||||||
|
|
||||||
<!ELEMENT variables (family*, separators*)>
|
<!ELEMENT variables (family*, separators*)>
|
||||||
<!ELEMENT family (#PCDATA | variable)*>
|
<!ELEMENT family (#PCDATA | variable)*>
|
||||||
<!ATTLIST family name CDATA #REQUIRED>
|
<!ATTLIST family name CDATA #REQUIRED>
|
||||||
<!ATTLIST family description CDATA #IMPLIED>
|
<!ATTLIST family description CDATA #IMPLIED>
|
||||||
<!ATTLIST family mode (basic|normal|expert) "basic">
|
<!ATTLIST family mode (basic|normal|expert) "basic">
|
||||||
<!ATTLIST family icon CDATA #IMPLIED>
|
|
||||||
<!ATTLIST family hidden (True|False) "False">
|
<!ATTLIST family hidden (True|False) "False">
|
||||||
<!ATTLIST family dynamic CDATA #IMPLIED>
|
<!ATTLIST family dynamic CDATA #IMPLIED>
|
||||||
|
|
||||||
|
@ -134,7 +102,6 @@
|
||||||
<!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">
|
||||||
<!ATTLIST variable submulti (True|False) "False">
|
|
||||||
<!ATTLIST variable redefine (True|False) "False">
|
<!ATTLIST variable redefine (True|False) "False">
|
||||||
<!ATTLIST variable exists (True|False) "True">
|
<!ATTLIST variable exists (True|False) "True">
|
||||||
<!ATTLIST variable mandatory (True|False) "False">
|
<!ATTLIST variable mandatory (True|False) "False">
|
||||||
|
@ -149,11 +116,10 @@
|
||||||
|
|
||||||
<!ELEMENT separator (#PCDATA)>
|
<!ELEMENT separator (#PCDATA)>
|
||||||
<!ATTLIST separator name CDATA #REQUIRED>
|
<!ATTLIST separator name CDATA #REQUIRED>
|
||||||
<!ATTLIST separator never_hidden CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT value (#PCDATA)>
|
<!ELEMENT value (#PCDATA)>
|
||||||
|
|
||||||
<!ELEMENT constraints ((fill* | check* | condition* | auto* | group*)*)>
|
<!ELEMENT constraints ((fill* | check* | condition* | group*)*)>
|
||||||
<!ELEMENT fill (param*)>
|
<!ELEMENT fill (param*)>
|
||||||
<!ATTLIST fill name CDATA #REQUIRED>
|
<!ATTLIST fill name CDATA #REQUIRED>
|
||||||
<!ATTLIST fill target CDATA #REQUIRED>
|
<!ATTLIST fill target CDATA #REQUIRED>
|
||||||
|
@ -163,29 +129,27 @@
|
||||||
<!ATTLIST check target CDATA #REQUIRED>
|
<!ATTLIST check target CDATA #REQUIRED>
|
||||||
<!ATTLIST check level (error|warning) "error">
|
<!ATTLIST check level (error|warning) "error">
|
||||||
|
|
||||||
<!ELEMENT auto ((param)*)>
|
|
||||||
<!ATTLIST auto name CDATA #REQUIRED>
|
|
||||||
<!ATTLIST auto target CDATA #REQUIRED>
|
|
||||||
|
|
||||||
<!ELEMENT condition ((target | param)+ )>
|
<!ELEMENT condition ((target | param)+ )>
|
||||||
<!ATTLIST condition name CDATA #REQUIRED>
|
<!ATTLIST condition name (disabled_if_in|disabled_if_not_in|hidden_if_in|auto_hidden_if_not_in|hidden_if_not_in|mandatory_if_in|mandatory_if_not_in) #REQUIRED>
|
||||||
<!ATTLIST condition source CDATA #REQUIRED>
|
<!ATTLIST condition source CDATA #REQUIRED>
|
||||||
<!ATTLIST condition fallback (True|False) "False">
|
<!ATTLIST condition fallback (True|False) "False">
|
||||||
|
<!ATTLIST condition force_condition_on_fallback (True|False) "False">
|
||||||
|
<!ATTLIST condition force_inverse_condition_on_fallback (True|False) "False">
|
||||||
|
|
||||||
<!ELEMENT group (slave+)>
|
<!ELEMENT group (follower+)>
|
||||||
<!ATTLIST group master CDATA #REQUIRED>
|
<!ATTLIST group leader CDATA #REQUIRED>
|
||||||
<!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|variable|number|python) "string">
|
||||||
<!ATTLIST param name CDATA #IMPLIED>
|
<!ATTLIST param name CDATA #IMPLIED>
|
||||||
<!ATTLIST param hidden (True|False) "True">
|
<!ATTLIST param notraisepropertyerror (True|False) "False">
|
||||||
<!ATTLIST param optional (True|False) "False">
|
<!ATTLIST param optional (True|False) "False">
|
||||||
|
|
||||||
<!ELEMENT target (#PCDATA)>
|
<!ELEMENT target (#PCDATA)>
|
||||||
<!ATTLIST target type (family|variable|filelist|iplist|portlist|tcpwrapperlist|packagelist|actionlist) "variable">
|
<!ATTLIST target type (family|variable|filelist|iplist|portlist) "variable">
|
||||||
<!ATTLIST target optional (True|False) "False">
|
<!ATTLIST target optional (True|False) "False">
|
||||||
|
|
||||||
<!ELEMENT slave (#PCDATA)>
|
<!ELEMENT follower (#PCDATA)>
|
||||||
|
|
||||||
<!ELEMENT help ((variable* | family*)*)>
|
<!ELEMENT help ((variable* | family*)*)>
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
|
||||||
Erreurs Creole
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigError(Exception):
|
class ConfigError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -19,7 +14,7 @@ class TemplateDisabled(TemplateError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CreoleOperationError(Exception):
|
class OperationError(Exception):
|
||||||
"""Type error or value Error for Creole variable's type or values
|
"""Type error or value Error for Creole variable's type or values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -30,7 +25,11 @@ class SpaceObjShallNotBeUpdated(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class CreoleDictConsistencyError(Exception):
|
class DictConsistencyError(Exception):
|
||||||
"""It's not only that the Creole XML is valid against the Creole DTD
|
"""It's not only that the Creole XML is valid against the Creole DTD
|
||||||
it's that it is not consistent.
|
it's that it is not consistent.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class LoaderError(Exception):
|
||||||
|
pass
|
||||||
|
|
|
@ -24,7 +24,7 @@ import sys
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
# Application Name
|
# Application Name
|
||||||
APP_NAME = 'creole'
|
APP_NAME = 'rougail'
|
||||||
|
|
||||||
# Traduction dir
|
# Traduction dir
|
||||||
APP_DIR = os.path.join(sys.prefix, 'share')
|
APP_DIR = os.path.join(sys.prefix, 'share')
|
||||||
|
@ -44,8 +44,8 @@ mo_location = LOCALE_DIR
|
||||||
|
|
||||||
gettext.find(APP_NAME, mo_location)
|
gettext.find(APP_NAME, mo_location)
|
||||||
gettext.textdomain(APP_NAME)
|
gettext.textdomain(APP_NAME)
|
||||||
gettext.bind_textdomain_codeset(APP_NAME, "UTF-8")
|
#gettext.bind_textdomain_codeset(APP_NAME, "UTF-8")
|
||||||
gettext.translation(APP_NAME, fallback=True)
|
#gettext.translation(APP_NAME, fallback=True)
|
||||||
|
|
||||||
t = gettext.translation(APP_NAME, fallback=True)
|
t = gettext.translation(APP_NAME, fallback=True)
|
||||||
|
|
||||||
|
|
|
@ -1,594 +0,0 @@
|
||||||
"""creole loader
|
|
||||||
flattened XML specific
|
|
||||||
"""
|
|
||||||
from os.path import join, isfile, isdir
|
|
||||||
from os import listdir
|
|
||||||
#from ast import literal_eval
|
|
||||||
from lxml.etree import parse, DTD
|
|
||||||
|
|
||||||
from tiramisu import (StrOption, OptionDescription, DynOptionDescription, PortOption,
|
|
||||||
IntOption, ChoiceOption, BoolOption, SymLinkOption, IPOption,
|
|
||||||
NetworkOption, NetmaskOption, DomainnameOption, BroadcastOption,
|
|
||||||
URLOption, EmailOption, FilenameOption, UsernameOption, DateOption,
|
|
||||||
PasswordOption, BoolOption, MACOption, Leadership, submulti,
|
|
||||||
Params, ParamSelfOption, ParamOption, ParamValue, Calculation, calc_value,
|
|
||||||
groups, owners)
|
|
||||||
from tiramisu.error import ConfigError
|
|
||||||
|
|
||||||
from .config import dtdfilename
|
|
||||||
from .i18n import _
|
|
||||||
#For compatibility
|
|
||||||
from .xmlreflector import HIGH_COMPATIBILITY
|
|
||||||
#from . import eosfunc
|
|
||||||
from .objspace import CreoleObjSpace
|
|
||||||
from .utils import normalize_family
|
|
||||||
import imp
|
|
||||||
|
|
||||||
|
|
||||||
FUNC_TO_DICT = ['valid_not_equal']
|
|
||||||
|
|
||||||
|
|
||||||
class ConvertDynOptionDescription(DynOptionDescription):
|
|
||||||
def convert_suffix_to_path(self, suffix):
|
|
||||||
if not isinstance(suffix, str):
|
|
||||||
suffix = str(suffix)
|
|
||||||
return normalize_family(suffix,
|
|
||||||
check_name=False)
|
|
||||||
|
|
||||||
|
|
||||||
class CreoleLoaderError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def convert_tiramisu_value(value, obj):
|
|
||||||
"""
|
|
||||||
convertit les variables dans le bon type si nécessaire
|
|
||||||
"""
|
|
||||||
if value is None:
|
|
||||||
return value
|
|
||||||
def _convert_boolean(value):
|
|
||||||
if isinstance(value, bool):
|
|
||||||
return value
|
|
||||||
prop = {'True': True,
|
|
||||||
'False': False,
|
|
||||||
'None': None}
|
|
||||||
if value not in prop:
|
|
||||||
raise Exception('unknown value {} while trying to cast {} to boolean'.format(value, obj))
|
|
||||||
return prop[value]
|
|
||||||
|
|
||||||
func = {IntOption: int, StrOption: str, PortOption: str,
|
|
||||||
DomainnameOption: str, EmailOption: str, URLOption: str,
|
|
||||||
IPOption: str, NetmaskOption: str, NetworkOption: str,
|
|
||||||
BroadcastOption: str, FilenameOption: str,
|
|
||||||
BoolOption: _convert_boolean}.get(obj, None)
|
|
||||||
if func is None:
|
|
||||||
return value
|
|
||||||
if isinstance(value, list):
|
|
||||||
return [func(val) for val in value]
|
|
||||||
else:
|
|
||||||
return func(value)
|
|
||||||
|
|
||||||
|
|
||||||
CONVERT_OPTION = {'number': dict(opttype=IntOption),
|
|
||||||
'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': True, 'allow_without_dot': True}),
|
|
||||||
'domain_strict': dict(opttype=DomainnameOption, initkwargs={'type': 'domainname', 'allow_ip': False}),
|
|
||||||
'hostname': dict(opttype=DomainnameOption, initkwargs={'type': 'hostname', 'allow_ip': True}),
|
|
||||||
'hostname_strict': 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 Elt(object):
|
|
||||||
def __init__(self, attrib):
|
|
||||||
self.attrib = attrib
|
|
||||||
|
|
||||||
|
|
||||||
class PopulateTiramisuObjects(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.storage = ElementStorage()
|
|
||||||
self.booleans = []
|
|
||||||
self.force_store_values = set()
|
|
||||||
self.separators = {}
|
|
||||||
self.groups = {}
|
|
||||||
|
|
||||||
def parse_dtd(self, dtdfilename):
|
|
||||||
"""Loads the Creole DTD
|
|
||||||
|
|
||||||
:raises IOError: if the DTD is not found
|
|
||||||
|
|
||||||
:param dtdfilename: the full filename of the Creole DTD
|
|
||||||
"""
|
|
||||||
if not isfile(dtdfilename):
|
|
||||||
raise IOError(_("no such DTD file: {}").format(dtdfilename))
|
|
||||||
with open(dtdfilename, 'r') as dtdfd:
|
|
||||||
dtd = DTD(dtdfd)
|
|
||||||
for elt in dtd.iterelements():
|
|
||||||
if elt.name == 'variable':
|
|
||||||
for attr in elt.iterattributes():
|
|
||||||
if set(attr.itervalues()) == set(['True', 'False']):
|
|
||||||
self.booleans.append(attr.name)
|
|
||||||
|
|
||||||
def make_tiramisu_objects(self, xmlroot, creolefunc_file):
|
|
||||||
elt = Elt({'name': 'baseoption'})
|
|
||||||
if creolefunc_file is None:
|
|
||||||
self.eosfunc = None
|
|
||||||
else:
|
|
||||||
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:
|
|
||||||
elts.setdefault(elt.tag, []).append(elt)
|
|
||||||
list_elts = list(elts.keys())
|
|
||||||
if 'family' in list_elts:
|
|
||||||
list_elts.remove('family')
|
|
||||||
list_elts.insert(0, 'family')
|
|
||||||
for elt in list_elts:
|
|
||||||
xmlelts_ = elts[elt]
|
|
||||||
if elt == 'family':
|
|
||||||
xmlelts = []
|
|
||||||
actions = None
|
|
||||||
# `creole` family has to be loaded before any other family
|
|
||||||
# because `extra` family could use `creole` variables.
|
|
||||||
# `actions` family has to be loaded at the very end
|
|
||||||
# because it may use `creole` or `extra` variables
|
|
||||||
for xml in xmlelts_:
|
|
||||||
if xml.attrib['name'] == 'creole':
|
|
||||||
xmlelts.insert(0, xml)
|
|
||||||
elif xml.attrib['name'] == 'actions':
|
|
||||||
actions = xml
|
|
||||||
else:
|
|
||||||
xmlelts.append(xml)
|
|
||||||
if actions is not None:
|
|
||||||
xmlelts.append(actions)
|
|
||||||
else:
|
|
||||||
xmlelts = xmlelts_
|
|
||||||
for xmlelt in xmlelts:
|
|
||||||
if xmlelt.tag != 'family':
|
|
||||||
raise CreoleLoaderError(_('unknown tag {}').format(xmlelt.tag))
|
|
||||||
self._iter_family(xmlelt, family)
|
|
||||||
|
|
||||||
def _populate_variable(self, elt, subpath, is_follower, is_leader):
|
|
||||||
variable = Variable(elt, self.booleans, self.storage, is_follower, is_leader, self.eosfunc)
|
|
||||||
path = self._build_path(subpath, elt)
|
|
||||||
properties = variable.attrib.get('properties', [])
|
|
||||||
if 'force_store_value' in properties or "auto_freeze" in properties:
|
|
||||||
self.force_store_values.add(path)
|
|
||||||
self.storage.add(path, variable)
|
|
||||||
return variable
|
|
||||||
|
|
||||||
def _populate_family(self, elt, subpath):
|
|
||||||
if subpath is None:
|
|
||||||
force_icon = False
|
|
||||||
else:
|
|
||||||
force_icon = not subpath.startswith('containers') and not subpath.startswith('actions')
|
|
||||||
family = Family(elt, self.booleans, self.storage, self.eosfunc, force_icon)
|
|
||||||
path = self._build_path(subpath, elt)
|
|
||||||
self.storage.add(path, family)
|
|
||||||
return family
|
|
||||||
|
|
||||||
def _build_path(self, subpath, elt):
|
|
||||||
if subpath is None:
|
|
||||||
subpath = elt.attrib['name']
|
|
||||||
else:
|
|
||||||
subpath += '.' + elt.attrib['name']
|
|
||||||
return subpath
|
|
||||||
|
|
||||||
def _iter_leader(self, leader, subpath):
|
|
||||||
subpath = self._build_path(subpath, leader)
|
|
||||||
family = Family(leader, self.booleans, self.storage, self.eosfunc)
|
|
||||||
family.set_leader()
|
|
||||||
self.storage.add(subpath, family)
|
|
||||||
leader_name = None
|
|
||||||
for var in leader:
|
|
||||||
if var.tag == 'property':
|
|
||||||
self._parse_properties(family, var)
|
|
||||||
elif var.tag == 'variable':
|
|
||||||
if leader_name is None:
|
|
||||||
leader_name = var.attrib['name']
|
|
||||||
self.groups[leader_name] = []
|
|
||||||
else:
|
|
||||||
self.groups[leader_name].append(var.attrib['name'])
|
|
||||||
self._iter_family(var, family, subpath=subpath)
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown tag {}').format(var.tag))
|
|
||||||
return family
|
|
||||||
|
|
||||||
def _iter_family(self, child, family, subpath=None):
|
|
||||||
if child.tag not in ['family', 'variable', 'separators', 'leader', 'property']:
|
|
||||||
raise CreoleLoaderError(_('unknown tag {}').format(child.tag))
|
|
||||||
if child.tag == 'family':
|
|
||||||
old_family = family
|
|
||||||
family = self._populate_family(child, subpath)
|
|
||||||
if old_family is not None:
|
|
||||||
old_family.add(family)
|
|
||||||
if len(child) != 0:
|
|
||||||
subpath = self._build_path(subpath, child)
|
|
||||||
for c in child:
|
|
||||||
self._iter_family(c, family, subpath=subpath)
|
|
||||||
elif child.tag == 'leader':
|
|
||||||
leader = self._iter_leader(child, subpath)
|
|
||||||
family.add(leader)
|
|
||||||
elif child.tag == 'separators':
|
|
||||||
self._parse_separators(child)
|
|
||||||
elif child.tag == 'variable':
|
|
||||||
if family is None:
|
|
||||||
raise CreoleLoaderError(_('variable without family'))
|
|
||||||
|
|
||||||
is_follower = False
|
|
||||||
is_leader = False
|
|
||||||
if family.is_leader:
|
|
||||||
if child.attrib['name'] != family.attrib['name']:
|
|
||||||
is_follower = True
|
|
||||||
else:
|
|
||||||
is_leader = True
|
|
||||||
variable = self._populate_variable(child, subpath, is_follower, is_leader)
|
|
||||||
family.add(variable)
|
|
||||||
elif child.tag == 'property':
|
|
||||||
self._parse_properties(family, child)
|
|
||||||
else:
|
|
||||||
raise Exception('unknown tag {}'.format(child.tag))
|
|
||||||
|
|
||||||
def _parse_properties(self, family, child):
|
|
||||||
if child.get('type') == 'calculation':
|
|
||||||
kwargs = {'condition': child.attrib['source'],
|
|
||||||
'expected': ParamValue(child.attrib.get('expected'))}
|
|
||||||
if child.attrib['inverse'] == 'True':
|
|
||||||
kwargs['reverse_condition'] = ParamValue(True)
|
|
||||||
family.attrib['properties'].append((ParamValue(child.text), kwargs))
|
|
||||||
else:
|
|
||||||
family.attrib['properties'].append(child.text)
|
|
||||||
|
|
||||||
def _parse_separators(self, separators):
|
|
||||||
for separator in separators:
|
|
||||||
elt = self.storage.get(separator.attrib['name'])
|
|
||||||
never_hidden = separator.attrib.get('never_hidden')
|
|
||||||
if never_hidden == 'True':
|
|
||||||
never_hidden = True
|
|
||||||
else:
|
|
||||||
never_hidden = None
|
|
||||||
info = (separator.text, never_hidden)
|
|
||||||
self.separators[separator.attrib['name']] = info
|
|
||||||
elt.add_information('separator', info)
|
|
||||||
|
|
||||||
|
|
||||||
class ElementStorage:
|
|
||||||
def __init__(self):
|
|
||||||
self.paths = {}
|
|
||||||
|
|
||||||
def add(self, path, elt):
|
|
||||||
if path in self.paths:
|
|
||||||
raise CreoleLoaderError(_('path already loaded {}').format(path))
|
|
||||||
self.paths[path] = elt
|
|
||||||
|
|
||||||
def add_information(self, path, name, information):
|
|
||||||
elt = self.get(path)
|
|
||||||
elt.add_information(name, information)
|
|
||||||
|
|
||||||
def get(self, path):
|
|
||||||
if path not in self.paths:
|
|
||||||
raise CreoleLoaderError(_('there is no element for path {}').format(path))
|
|
||||||
return self.paths[path]
|
|
||||||
|
|
||||||
|
|
||||||
class Common:
|
|
||||||
def build_properties(self):
|
|
||||||
for index, prop in enumerate(self.attrib['properties']):
|
|
||||||
if isinstance(prop, tuple):
|
|
||||||
action, kwargs = prop
|
|
||||||
kwargs['condition'] = ParamOption(self.storage.get(kwargs['condition']).get(), todict=True)
|
|
||||||
prop = Calculation(calc_value,
|
|
||||||
Params(action,
|
|
||||||
kwargs=kwargs))
|
|
||||||
self.attrib['properties'][index] = prop
|
|
||||||
if self.attrib['properties']:
|
|
||||||
self.attrib['properties'] = tuple(self.attrib['properties'])
|
|
||||||
else:
|
|
||||||
del self.attrib['properties']
|
|
||||||
|
|
||||||
|
|
||||||
class Variable(Common):
|
|
||||||
def __init__(self, elt, booleans, storage, is_follower, is_leader, eosfunc):
|
|
||||||
self.option = None
|
|
||||||
self.informations = {}
|
|
||||||
self.attrib = {}
|
|
||||||
self.attrib['properties'] = []
|
|
||||||
self.attrib['validators'] = []
|
|
||||||
self.eosfunc = eosfunc
|
|
||||||
self.storage = storage
|
|
||||||
is_submulti = False
|
|
||||||
for key, value in elt.attrib.items():
|
|
||||||
if key in booleans:
|
|
||||||
if value == 'True':
|
|
||||||
value = True
|
|
||||||
elif value == 'False':
|
|
||||||
value = False
|
|
||||||
elif key == 'multi' and value == 'submulti':
|
|
||||||
is_submulti = True
|
|
||||||
value = submulti
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown value {} for {}').format(value, key))
|
|
||||||
if key in ['help', 'test']:
|
|
||||||
self.add_information(key, value)
|
|
||||||
elif key == 'type':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.attrib[key] = value
|
|
||||||
convert_option = CONVERT_OPTION[elt.attrib['type']]
|
|
||||||
self.object_type = convert_option['opttype']
|
|
||||||
if elt.attrib['type'] == 'choice':
|
|
||||||
if self.attrib.get('choice'):
|
|
||||||
self.attrib['values'] = getattr(self.eosfunc, self.attrib.get('choice'))
|
|
||||||
else:
|
|
||||||
self.attrib['values'] = []
|
|
||||||
for child in elt:
|
|
||||||
if child.tag == 'choice':
|
|
||||||
value = child.text
|
|
||||||
if 'type' in child.attrib and child.attrib['type'] == 'number':
|
|
||||||
value = int(value)
|
|
||||||
if value is None:
|
|
||||||
value = u''
|
|
||||||
self.attrib['values'].append(value)
|
|
||||||
self.attrib['values'] = tuple(self.attrib['values'])
|
|
||||||
for child in elt:
|
|
||||||
if child.tag == 'property':
|
|
||||||
if child.get('type') == 'calculation':
|
|
||||||
kwargs = {'condition': child.attrib['source'],
|
|
||||||
'expected': ParamValue(child.attrib.get('expected'))}
|
|
||||||
if child.attrib['inverse'] == 'True':
|
|
||||||
kwargs['reverse_condition'] = ParamValue(True)
|
|
||||||
self.attrib['properties'].append((ParamValue(child.text), kwargs))
|
|
||||||
else:
|
|
||||||
self.attrib['properties'].append(child.text)
|
|
||||||
elif child.tag == 'value':
|
|
||||||
if child.attrib.get('type') == 'calculation':
|
|
||||||
if child.text is not None and child.text.strip():
|
|
||||||
self.attrib['default'] = (child.text.strip(),)
|
|
||||||
else:
|
|
||||||
params = []
|
|
||||||
for param in child:
|
|
||||||
params.append(self.parse_param(param))
|
|
||||||
self.attrib['default'] = (child.attrib['name'], params, False)
|
|
||||||
else:
|
|
||||||
if "type" in child.attrib:
|
|
||||||
type_ = CONVERT_OPTION[child.attrib['type']]['opttype']
|
|
||||||
else:
|
|
||||||
type_ = self.object_type
|
|
||||||
if self.attrib['multi'] is True and not is_follower:
|
|
||||||
if 'default' not in self.attrib:
|
|
||||||
self.attrib['default'] = []
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
self.attrib['default'].append(value)
|
|
||||||
if 'default_multi' not in self.attrib and not is_leader:
|
|
||||||
self.attrib['default_multi'] = value
|
|
||||||
elif self.attrib['multi'] == submulti:
|
|
||||||
if 'default' not in self.attrib:
|
|
||||||
self.attrib['default'] = []
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
if not isinstance(value, list) and not is_follower:
|
|
||||||
value = [value]
|
|
||||||
self.attrib['default'].append(value)
|
|
||||||
if 'default_multi' not in self.attrib and not is_leader:
|
|
||||||
self.attrib['default_multi'] = value
|
|
||||||
else:
|
|
||||||
if 'default' in self.attrib:
|
|
||||||
raise CreoleLoaderError(_('default value already set for {}'
|
|
||||||
'').format(self.attrib['path']))
|
|
||||||
value = convert_tiramisu_value(child.text, type_)
|
|
||||||
if value is None: # and (elt.attrib['type'] != 'choice' or value not in self.attrib['values']):
|
|
||||||
value = u''
|
|
||||||
if is_follower:
|
|
||||||
self.attrib['default_multi'] = value
|
|
||||||
else:
|
|
||||||
self.attrib['default'] = value
|
|
||||||
elif child.tag == 'choice':
|
|
||||||
# already load
|
|
||||||
pass
|
|
||||||
elif child.tag == 'check':
|
|
||||||
params = []
|
|
||||||
for param in child:
|
|
||||||
params.append(self.parse_param(param))
|
|
||||||
#check.params = params
|
|
||||||
self.attrib['validators'].append((child.attrib['name'], params, child.attrib['warnings_only']))
|
|
||||||
else:
|
|
||||||
raise Exception('unknown tag {}'.format(child.tag))
|
|
||||||
if 'initkwargs' in convert_option:
|
|
||||||
self.attrib.update(convert_option['initkwargs'])
|
|
||||||
if elt.attrib['type'] == 'symlink':
|
|
||||||
del self.attrib['properties']
|
|
||||||
del self.attrib['multi']
|
|
||||||
self.attrib['opt'] = storage.get(self.attrib['opt'])
|
|
||||||
|
|
||||||
def parse_param(self, param):
|
|
||||||
name = param.attrib.get('name', '')
|
|
||||||
if param.attrib['type'] == 'string':
|
|
||||||
value = param.text
|
|
||||||
elif param.attrib['type'] == 'variable':
|
|
||||||
transitive = param.attrib.get('transitive', 'False')
|
|
||||||
if transitive == 'True':
|
|
||||||
transitive = True
|
|
||||||
elif transitive == 'False':
|
|
||||||
transitive = False
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown transitive boolean {}').format(transitive))
|
|
||||||
value = [param.text, transitive]
|
|
||||||
elif param.attrib['type'] == 'number':
|
|
||||||
value = int(param.text)
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown param type {}').format(param.attrib['type']))
|
|
||||||
return(name, value)
|
|
||||||
|
|
||||||
def add_information(self, key, value):
|
|
||||||
if key in self.informations:
|
|
||||||
raise CreoleLoaderError(_('key already exists in information {}').format(key))
|
|
||||||
self.informations[key] = value
|
|
||||||
|
|
||||||
def build_calculator(self, key):
|
|
||||||
if key in self.attrib:
|
|
||||||
values = self.attrib[key]
|
|
||||||
if isinstance(values, list):
|
|
||||||
is_list = True
|
|
||||||
else:
|
|
||||||
is_list = False
|
|
||||||
values = [values]
|
|
||||||
ret = []
|
|
||||||
for value in values:
|
|
||||||
if isinstance(value, tuple):
|
|
||||||
if key == 'validators':
|
|
||||||
args = [ParamSelfOption()]
|
|
||||||
else:
|
|
||||||
args = []
|
|
||||||
kwargs = {}
|
|
||||||
if len(value) == 3:
|
|
||||||
for param in value[1]:
|
|
||||||
if isinstance(param[1], list):
|
|
||||||
if value[0] in FUNC_TO_DICT:
|
|
||||||
param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1], todict=True)
|
|
||||||
else:
|
|
||||||
param_value = ParamOption(self.storage.get(param[1][0]).get(), notraisepropertyerror=param[1][1])
|
|
||||||
else:
|
|
||||||
param_value = ParamValue(param[1])
|
|
||||||
if not param[0]:
|
|
||||||
args.append(param_value)
|
|
||||||
else:
|
|
||||||
kwargs[param[0]] = param_value
|
|
||||||
|
|
||||||
ret.append(Calculation(getattr(self.eosfunc, value[0]),
|
|
||||||
Params(tuple(args),
|
|
||||||
kwargs=kwargs)))
|
|
||||||
else:
|
|
||||||
ret.append(value)
|
|
||||||
if not is_list:
|
|
||||||
self.attrib[key] = ret[0]
|
|
||||||
else:
|
|
||||||
self.attrib[key] = ret
|
|
||||||
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
if self.option is None:
|
|
||||||
if self.object_type is SymLinkOption:
|
|
||||||
self.attrib['opt'] = self.attrib['opt'].get()
|
|
||||||
else:
|
|
||||||
self.build_properties()
|
|
||||||
self.build_calculator('default')
|
|
||||||
self.build_calculator('validators')
|
|
||||||
if not self.attrib['validators']:
|
|
||||||
del self.attrib['validators']
|
|
||||||
try:
|
|
||||||
option = self.object_type(**self.attrib)
|
|
||||||
except Exception as err:
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
name = self.attrib['name']
|
|
||||||
raise CreoleLoaderError(_('cannot create option {}: {}').format(name, err))
|
|
||||||
for key, value in self.informations.items():
|
|
||||||
option.impl_set_information(key, value)
|
|
||||||
self.option = option
|
|
||||||
return self.option
|
|
||||||
|
|
||||||
|
|
||||||
class Family(Common):
|
|
||||||
def __init__(self, elt, booleans, storage, eosfunc, force_icon=False):
|
|
||||||
self.option = None
|
|
||||||
self.attrib = {}
|
|
||||||
self.is_leader = False
|
|
||||||
if force_icon:
|
|
||||||
self.informations = {'icon': None}
|
|
||||||
else:
|
|
||||||
self.informations = {}
|
|
||||||
self.children = []
|
|
||||||
self.storage = storage
|
|
||||||
self.eosfunc = eosfunc
|
|
||||||
self.attrib['properties'] = []
|
|
||||||
for key, value in elt.attrib.items():
|
|
||||||
if key in booleans:
|
|
||||||
if value == 'True':
|
|
||||||
value = True
|
|
||||||
elif value == 'False':
|
|
||||||
value = False
|
|
||||||
else:
|
|
||||||
raise CreoleLoaderError(_('unknown value {} for {}').format(value, key))
|
|
||||||
if key == 'icon':
|
|
||||||
self.add_information('icon', value)
|
|
||||||
continue
|
|
||||||
elif key == 'hidden':
|
|
||||||
if value:
|
|
||||||
self.attrib['properties'].append(key)
|
|
||||||
elif key == 'mode':
|
|
||||||
self.attrib['properties'].append(value)
|
|
||||||
elif key == 'help':
|
|
||||||
self.add_information(key, value)
|
|
||||||
elif key == 'type':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.attrib[key] = value
|
|
||||||
if 'doc' not in self.attrib:
|
|
||||||
self.attrib['doc'] = u''
|
|
||||||
|
|
||||||
def add(self, child):
|
|
||||||
self.children.append(child)
|
|
||||||
|
|
||||||
def add_information(self, key, value):
|
|
||||||
if key in self.informations and not (key == 'icon' and self.informations[key] is None):
|
|
||||||
raise CreoleLoaderError(_('key already exists in information {}').format(key))
|
|
||||||
self.informations[key] = value
|
|
||||||
|
|
||||||
def set_leader(self):
|
|
||||||
self.is_leader = True
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
if self.option is None:
|
|
||||||
self.attrib['children'] = []
|
|
||||||
for child in self.children:
|
|
||||||
self.attrib['children'].append(child.get())
|
|
||||||
self.build_properties()
|
|
||||||
try:
|
|
||||||
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 = ConvertDynOptionDescription(**self.attrib)
|
|
||||||
elif not self.is_leader:
|
|
||||||
option = OptionDescription(**self.attrib)
|
|
||||||
else:
|
|
||||||
option = Leadership(**self.attrib)
|
|
||||||
except Exception as err:
|
|
||||||
raise CreoleLoaderError(_('cannot create optiondescription {}: {}').format(self.attrib['name'], err))
|
|
||||||
for key, value in self.informations.items():
|
|
||||||
option.impl_set_information(key, value)
|
|
||||||
self.option = option
|
|
||||||
#if self.is_leader:
|
|
||||||
# self.option.impl_set_group_type(groups.leader)
|
|
||||||
|
|
||||||
return self.option
|
|
||||||
|
|
||||||
|
|
||||||
def load(xmlroot: str,
|
|
||||||
dtd_path: str,
|
|
||||||
funcs_path: str):
|
|
||||||
tiramisu_objects = PopulateTiramisuObjects()
|
|
||||||
tiramisu_objects.parse_dtd(dtd_path)
|
|
||||||
tiramisu_objects.make_tiramisu_objects(xmlroot,
|
|
||||||
funcs_path)
|
|
||||||
return tiramisu_objects.storage.paths['.'].get()
|
|
File diff suppressed because it is too large
Load diff
204
src/rougail/path.py
Normal file
204
src/rougail/path.py
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
from .i18n import _
|
||||||
|
from .utils import normalize_family
|
||||||
|
from .error import OperationError, DictConsistencyError
|
||||||
|
from .config import variable_namespace
|
||||||
|
|
||||||
|
|
||||||
|
class Path:
|
||||||
|
"""Helper class to handle the `path` attribute of a CreoleObjSpace
|
||||||
|
instance.
|
||||||
|
|
||||||
|
sample: path="creole.general.condition"
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
self.variables = {}
|
||||||
|
self.families = {}
|
||||||
|
self.full_paths = {}
|
||||||
|
|
||||||
|
# Family
|
||||||
|
def add_family(self,
|
||||||
|
namespace: str,
|
||||||
|
name: str,
|
||||||
|
variableobj: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
if '.' not in name and namespace == variable_namespace:
|
||||||
|
full_name = '.'.join([namespace, name])
|
||||||
|
self.full_paths[name] = full_name
|
||||||
|
else:
|
||||||
|
full_name = name
|
||||||
|
if full_name in self.families and self.families[full_name]['variableobj'] != variableobj:
|
||||||
|
raise DictConsistencyError(_(f'Duplicate family name {name}'))
|
||||||
|
self.families[full_name] = dict(name=name,
|
||||||
|
namespace=namespace,
|
||||||
|
variableobj=variableobj,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_family_path(self,
|
||||||
|
name: str,
|
||||||
|
current_namespace: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
name = normalize_family(name,
|
||||||
|
check_name=False,
|
||||||
|
allow_dot=True,
|
||||||
|
)
|
||||||
|
if '.' not in name and current_namespace == variable_namespace and name in self.full_paths:
|
||||||
|
name = self.full_paths[name]
|
||||||
|
if current_namespace is None: # pragma: no cover
|
||||||
|
raise OperationError('current_namespace must not be None')
|
||||||
|
dico = self.families[name]
|
||||||
|
if dico['namespace'] != variable_namespace and current_namespace != dico['namespace']:
|
||||||
|
raise DictConsistencyError(_('A family located in the {} namespace '
|
||||||
|
'shall not be used in the {} namespace').format(
|
||||||
|
dico['namespace'], current_namespace))
|
||||||
|
return dico['name']
|
||||||
|
|
||||||
|
def get_family_obj(self,
|
||||||
|
name: str,
|
||||||
|
) -> 'Family': # pylint: disable=C0111
|
||||||
|
if '.' not in name and name in self.full_paths:
|
||||||
|
name = self.full_paths[name]
|
||||||
|
if name not in self.families:
|
||||||
|
raise DictConsistencyError(_('unknown family {}').format(name))
|
||||||
|
dico = self.families[name]
|
||||||
|
return dico['variableobj']
|
||||||
|
|
||||||
|
def family_is_defined(self,
|
||||||
|
name: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
if '.' not in name and name not in self.families and name in self.full_paths:
|
||||||
|
return True
|
||||||
|
return name in self.families
|
||||||
|
|
||||||
|
# Leadership
|
||||||
|
def set_leader(self,
|
||||||
|
namespace: str,
|
||||||
|
leader_family_name: str,
|
||||||
|
name: str,
|
||||||
|
leader_name: str,
|
||||||
|
) -> None: # pylint: disable=C0111
|
||||||
|
# need rebuild path and move object in new path
|
||||||
|
old_path = namespace + '.' + leader_family_name + '.' + name
|
||||||
|
dico = self._get_variable(old_path)
|
||||||
|
del self.variables[old_path]
|
||||||
|
new_path = namespace + '.' + leader_family_name + '.' + leader_name + '.' + name
|
||||||
|
self.add_variable(namespace,
|
||||||
|
new_path,
|
||||||
|
dico['family'],
|
||||||
|
False,
|
||||||
|
dico['variableobj'],
|
||||||
|
)
|
||||||
|
if namespace == variable_namespace:
|
||||||
|
self.full_paths[name] = new_path
|
||||||
|
else:
|
||||||
|
name = new_path
|
||||||
|
dico = self._get_variable(name)
|
||||||
|
if dico['leader'] != None:
|
||||||
|
raise DictConsistencyError(_('Already defined leader {} for variable'
|
||||||
|
' {}'.format(dico['leader'], name)))
|
||||||
|
dico['leader'] = leader_name
|
||||||
|
|
||||||
|
def get_leader(self, name): # pylint: disable=C0111
|
||||||
|
return self._get_variable(name)['leader']
|
||||||
|
|
||||||
|
# Variable
|
||||||
|
def add_variable(self,
|
||||||
|
namespace: str,
|
||||||
|
name: str,
|
||||||
|
family: str,
|
||||||
|
is_dynamic: bool,
|
||||||
|
variableobj,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
if '.' not in name:
|
||||||
|
full_name = '.'.join([namespace, family, name])
|
||||||
|
self.full_paths[name] = full_name
|
||||||
|
else:
|
||||||
|
full_name = name
|
||||||
|
if namespace == variable_namespace:
|
||||||
|
name = name.rsplit('.', 1)[1]
|
||||||
|
self.variables[full_name] = dict(name=name,
|
||||||
|
family=family,
|
||||||
|
namespace=namespace,
|
||||||
|
leader=None,
|
||||||
|
is_dynamic=is_dynamic,
|
||||||
|
variableobj=variableobj)
|
||||||
|
|
||||||
|
def get_variable_name(self,
|
||||||
|
name,
|
||||||
|
): # pylint: disable=C0111
|
||||||
|
return self._get_variable(name)['name']
|
||||||
|
|
||||||
|
def get_variable_obj(self,
|
||||||
|
name:str,
|
||||||
|
) -> 'Variable': # pylint: disable=C0111
|
||||||
|
return self._get_variable(name)['variableobj']
|
||||||
|
|
||||||
|
def get_variable_family_name(self,
|
||||||
|
name: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
return self._get_variable(name)['family']
|
||||||
|
|
||||||
|
def get_variable_namespace(self,
|
||||||
|
name: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
return self._get_variable(name)['namespace']
|
||||||
|
|
||||||
|
def get_variable_path(self,
|
||||||
|
name: str,
|
||||||
|
current_namespace: str,
|
||||||
|
allow_source: str=False,
|
||||||
|
with_suffix: bool=False,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
if current_namespace is None: # pragma: no cover
|
||||||
|
raise OperationError('current_namespace must not be None')
|
||||||
|
if with_suffix:
|
||||||
|
dico, suffix = self._get_variable(name,
|
||||||
|
with_suffix=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
dico = self._get_variable(name)
|
||||||
|
if not allow_source:
|
||||||
|
if dico['namespace'] not in [variable_namespace, 'services'] and current_namespace != dico['namespace']:
|
||||||
|
raise DictConsistencyError(_('A variable located in the {} namespace '
|
||||||
|
'shall not be used in the {} namespace').format(
|
||||||
|
dico['namespace'], current_namespace))
|
||||||
|
if '.' in dico['name']:
|
||||||
|
value = dico['name']
|
||||||
|
else:
|
||||||
|
list_path = [dico['namespace'], dico['family']]
|
||||||
|
if dico['leader'] is not None:
|
||||||
|
list_path.append(dico['leader'])
|
||||||
|
list_path.append(dico['name'])
|
||||||
|
value = '.'.join(list_path)
|
||||||
|
if with_suffix:
|
||||||
|
return value, suffix
|
||||||
|
return value
|
||||||
|
|
||||||
|
def path_is_defined(self,
|
||||||
|
name: str,
|
||||||
|
) -> str: # pylint: disable=C0111
|
||||||
|
if '.' not in name and name not in self.variables and name in self.full_paths:
|
||||||
|
return True
|
||||||
|
return name in self.variables
|
||||||
|
|
||||||
|
def _get_variable(self,
|
||||||
|
name: str,
|
||||||
|
with_suffix: bool=False,
|
||||||
|
) -> str:
|
||||||
|
if name not in self.variables:
|
||||||
|
if name not in self.variables:
|
||||||
|
if '.' not in name and name in self.full_paths:
|
||||||
|
name = self.full_paths[name]
|
||||||
|
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):]
|
||||||
|
if '.' not in name:
|
||||||
|
for var_name, path in self.full_paths.items():
|
||||||
|
if name.startswith(var_name):
|
||||||
|
variable = self.variables[self.full_paths[var_name]]
|
||||||
|
if variable['is_dynamic']:
|
||||||
|
return variable, name[len(var_name):]
|
||||||
|
raise DictConsistencyError(_('unknown option {}').format(name))
|
||||||
|
if with_suffix:
|
||||||
|
return self.variables[name], None
|
||||||
|
return self.variables[name]
|
|
@ -5,32 +5,12 @@ On travaille sur les fichiers cibles
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import sys
|
|
||||||
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, unlink, makedirs
|
from os import listdir, makedirs
|
||||||
from os.path import dirname, basename, join, split, isfile, isdir
|
from os.path import dirname, join, isfile
|
||||||
|
|
||||||
from tempfile import mktemp
|
|
||||||
|
|
||||||
from Cheetah import Parser
|
|
||||||
|
|
||||||
|
|
||||||
# l'encoding du template est déterminé par une regexp (encodingDirectiveRE dans Parser.py)
|
|
||||||
# il cherche un ligne qui ressemble à '#encoding: utf-8
|
|
||||||
# cette classe simule le module 're' et retourne toujours l'encoding utf-8
|
|
||||||
# 6224
|
|
||||||
class FakeEncoding:
|
|
||||||
def groups(self):
|
|
||||||
return ('utf-8',)
|
|
||||||
|
|
||||||
def search(self, *args):
|
|
||||||
return self
|
|
||||||
Parser.encodingDirectiveRE = FakeEncoding()
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -38,8 +18,8 @@ from Cheetah.NameMapper import NotFound as CheetahNotFound
|
||||||
from tiramisu import Config
|
from tiramisu import Config
|
||||||
from tiramisu.error import PropertiesOptionError
|
from tiramisu.error import PropertiesOptionError
|
||||||
|
|
||||||
from .config import patch_dir
|
from .config import patch_dir, variable_namespace
|
||||||
from .error import FileNotFound, TemplateError, TemplateDisabled
|
from .error import FileNotFound, TemplateError
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .utils import normalize_family
|
from .utils import normalize_family
|
||||||
|
|
||||||
|
@ -47,6 +27,7 @@ from .utils import normalize_family
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
log.addHandler(logging.NullHandler())
|
log.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
|
||||||
class IsDefined:
|
class IsDefined:
|
||||||
"""
|
"""
|
||||||
filtre permettant de ne pas lever d'exception au cas où
|
filtre permettant de ne pas lever d'exception au cas où
|
||||||
|
@ -59,34 +40,16 @@ class IsDefined:
|
||||||
if '.' in varname:
|
if '.' in varname:
|
||||||
splitted_var = varname.split('.')
|
splitted_var = varname.split('.')
|
||||||
if len(splitted_var) != 2:
|
if len(splitted_var) != 2:
|
||||||
msg = _("Group variables must be of type master.slave")
|
msg = _("Group variables must be of type leader.follower")
|
||||||
raise KeyError(msg)
|
raise KeyError(msg)
|
||||||
master, slave = splitted_var
|
leader, follower = splitted_var
|
||||||
if master in self.context:
|
if leader in self.context:
|
||||||
return slave in self.context[master].slave.keys()
|
return follower in self.context[leader].follower.keys()
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return varname in self.context
|
return varname in self.context
|
||||||
|
|
||||||
|
|
||||||
class CreoleGet:
|
|
||||||
def __init__(self, context):
|
|
||||||
self.context = context
|
|
||||||
|
|
||||||
def __call__(self, varname):
|
|
||||||
return self.context[varname]
|
|
||||||
|
|
||||||
def __getitem__(self, varname):
|
|
||||||
"""For bracket and dotted notation
|
|
||||||
"""
|
|
||||||
return self.context[varname]
|
|
||||||
|
|
||||||
def __contains__(self, varname):
|
|
||||||
"""Check variable existence in context
|
|
||||||
"""
|
|
||||||
return varname in self.context
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cl_compile(kls, *args, **kwargs):
|
def cl_compile(kls, *args, **kwargs):
|
||||||
kwargs['compilerSettings'] = {'directiveStartToken' : '%',
|
kwargs['compilerSettings'] = {'directiveStartToken' : '%',
|
||||||
|
@ -103,12 +66,6 @@ ChtTemplate.old_compile = ChtTemplate.compile
|
||||||
ChtTemplate.compile = cl_compile
|
ChtTemplate.compile = cl_compile
|
||||||
|
|
||||||
|
|
||||||
class CreoleClient:
|
|
||||||
def __init__(self,
|
|
||||||
config: Config):
|
|
||||||
self.config = config
|
|
||||||
|
|
||||||
|
|
||||||
class CheetahTemplate(ChtTemplate):
|
class CheetahTemplate(ChtTemplate):
|
||||||
"""classe pour personnaliser et faciliter la construction
|
"""classe pour personnaliser et faciliter la construction
|
||||||
du template Cheetah
|
du template Cheetah
|
||||||
|
@ -133,7 +90,7 @@ class CheetahTemplate(ChtTemplate):
|
||||||
|
|
||||||
|
|
||||||
class CreoleLeader:
|
class CreoleLeader:
|
||||||
def __init__(self, value, slave=None, index=None):
|
def __init__(self, value, follower=None, index=None):
|
||||||
"""
|
"""
|
||||||
On rend la variable itérable pour pouvoir faire:
|
On rend la variable itérable pour pouvoir faire:
|
||||||
for ip in iplist:
|
for ip in iplist:
|
||||||
|
@ -143,20 +100,20 @@ class CreoleLeader:
|
||||||
index is used for CreoleLint
|
index is used for CreoleLint
|
||||||
"""
|
"""
|
||||||
self._value = value
|
self._value = value
|
||||||
if slave is not None:
|
if follower is not None:
|
||||||
self.slave = slave
|
self.follower = follower
|
||||||
else:
|
else:
|
||||||
self.slave = {}
|
self.follower = {}
|
||||||
self._index = index
|
self._index = index
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
"""Get slave variable or attribute of master value.
|
"""Get follower variable or attribute of leader value.
|
||||||
|
|
||||||
If the attribute is a name of a slave variable, return its value.
|
If the attribute is a name of a follower variable, return its value.
|
||||||
Otherwise, returns the requested attribute of master value.
|
Otherwise, returns the requested attribute of leader value.
|
||||||
"""
|
"""
|
||||||
if name in self.slave:
|
if name in self.follower:
|
||||||
value = self.slave[name]
|
value = self.follower[name]
|
||||||
if isinstance(value, PropertiesOptionError):
|
if isinstance(value, PropertiesOptionError):
|
||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
return value
|
return value
|
||||||
|
@ -164,36 +121,36 @@ class CreoleLeader:
|
||||||
return getattr(self._value, name)
|
return getattr(self._value, name)
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"""Get a master.slave at requested index.
|
"""Get a leader.follower at requested index.
|
||||||
"""
|
"""
|
||||||
ret = {}
|
ret = {}
|
||||||
for key, values in self.slave.items():
|
for key, values in self.follower.items():
|
||||||
ret[key] = values[index]
|
ret[key] = values[index]
|
||||||
return CreoleLeader(self._value[index], ret, index)
|
return CreoleLeader(self._value[index], ret, index)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Iterate over master.slave.
|
"""Iterate over leader.follower.
|
||||||
|
|
||||||
Return synchronised value of master.slave.
|
Return synchronised value of leader.follower.
|
||||||
"""
|
"""
|
||||||
for i in range(len(self._value)):
|
for i in range(len(self._value)):
|
||||||
ret = {}
|
ret = {}
|
||||||
for key, values in self.slave.items():
|
for key, values in self.follower.items():
|
||||||
ret[key] = values[i]
|
ret[key] = values[i]
|
||||||
yield CreoleLeader(self._value[i], ret, i)
|
yield CreoleLeader(self._value[i], ret, i)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Delegate to master value
|
"""Delegate to leader value
|
||||||
"""
|
"""
|
||||||
return len(self._value)
|
return len(self._value)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
"""Show CreoleLeader as dictionary.
|
"""Show CreoleLeader as dictionary.
|
||||||
|
|
||||||
The master value is stored under 'value' key.
|
The leader value is stored under 'value' key.
|
||||||
The slaves are stored under 'slave' key.
|
The followers are stored under 'follower' key.
|
||||||
"""
|
"""
|
||||||
return repr({'value': self._value, 'slave': self.slave})
|
return repr({'value': self._value, 'follower': self.follower})
|
||||||
|
|
||||||
def __eq__(self, value):
|
def __eq__(self, value):
|
||||||
return value == self._value
|
return value == self._value
|
||||||
|
@ -214,7 +171,7 @@ class CreoleLeader:
|
||||||
return self._value >= value
|
return self._value >= value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Delegate to master value
|
"""Delegate to leader value
|
||||||
"""
|
"""
|
||||||
return str(self._value)
|
return str(self._value)
|
||||||
|
|
||||||
|
@ -227,7 +184,7 @@ class CreoleLeader:
|
||||||
def __contains__(self, item):
|
def __contains__(self, item):
|
||||||
return item in self._value
|
return item in self._value
|
||||||
|
|
||||||
async def add_slave(self, config, name, path):
|
async def add_follower(self, config, name, path):
|
||||||
if isinstance(self._value, list):
|
if isinstance(self._value, list):
|
||||||
values = []
|
values = []
|
||||||
for idx in range(len(self._value)):
|
for idx in range(len(self._value)):
|
||||||
|
@ -237,7 +194,7 @@ class CreoleLeader:
|
||||||
values.append(err)
|
values.append(err)
|
||||||
else:
|
else:
|
||||||
raise Exception('hu?')
|
raise Exception('hu?')
|
||||||
self.slave[name] = values
|
self.follower[name] = values
|
||||||
|
|
||||||
|
|
||||||
class CreoleExtra:
|
class CreoleExtra:
|
||||||
|
@ -252,6 +209,9 @@ class CreoleExtra:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.suboption.__str__()
|
return self.suboption.__str__()
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.suboption.values())
|
||||||
|
|
||||||
|
|
||||||
class CreoleTemplateEngine:
|
class CreoleTemplateEngine:
|
||||||
"""Engine to process Creole cheetah template
|
"""Engine to process Creole cheetah template
|
||||||
|
@ -261,7 +221,8 @@ class CreoleTemplateEngine:
|
||||||
eosfunc_file: str,
|
eosfunc_file: str,
|
||||||
distrib_dir: str,
|
distrib_dir: str,
|
||||||
tmp_dir: str,
|
tmp_dir: str,
|
||||||
dest_dir:str) -> None:
|
dest_dir: str,
|
||||||
|
) -> None:
|
||||||
self.config = config
|
self.config = config
|
||||||
self.dest_dir = dest_dir
|
self.dest_dir = dest_dir
|
||||||
self.tmp_dir = tmp_dir
|
self.tmp_dir = tmp_dir
|
||||||
|
@ -273,25 +234,25 @@ class CreoleTemplateEngine:
|
||||||
if not func.startswith('_'):
|
if not func.startswith('_'):
|
||||||
eos[func] = getattr(eosfunc, func)
|
eos[func] = getattr(eosfunc, func)
|
||||||
self.eosfunc = eos
|
self.eosfunc = eos
|
||||||
self.creole_variables_dict = {}
|
self.rougail_variables_dict = {}
|
||||||
|
|
||||||
async def load_eole_variables_creole(self,
|
async def load_eole_variables_rougail(self,
|
||||||
optiondescription):
|
optiondescription):
|
||||||
for option in await optiondescription.list('all'):
|
for option in await optiondescription.list('all'):
|
||||||
if await option.option.isoptiondescription():
|
if await option.option.isoptiondescription():
|
||||||
if await option.option.isleadership():
|
if await option.option.isleadership():
|
||||||
for idx, suboption in enumerate(await option.list('all')):
|
for idx, suboption in enumerate(await option.list('all')):
|
||||||
if idx == 0:
|
if idx == 0:
|
||||||
leader = CreoleLeader(await suboption.value.get())
|
leader = CreoleLeader(await suboption.value.get())
|
||||||
self.creole_variables_dict[await suboption.option.name()] = leader
|
self.rougail_variables_dict[await suboption.option.name()] = leader
|
||||||
else:
|
else:
|
||||||
await leader.add_slave(self.config,
|
await leader.add_follower(self.config,
|
||||||
await suboption.option.name(),
|
await suboption.option.name(),
|
||||||
await suboption.option.path())
|
await suboption.option.path())
|
||||||
else:
|
else:
|
||||||
await self.load_eole_variables_creole(option)
|
await self.load_eole_variables_rougail(option)
|
||||||
else:
|
else:
|
||||||
self.creole_variables_dict[await option.option.name()] = await option.value.get()
|
self.rougail_variables_dict[await option.option.name()] = await option.value.get()
|
||||||
|
|
||||||
async def load_eole_variables(self,
|
async def load_eole_variables(self,
|
||||||
namespace,
|
namespace,
|
||||||
|
@ -300,20 +261,26 @@ class CreoleTemplateEngine:
|
||||||
for family in await optiondescription.list('all'):
|
for family in await optiondescription.list('all'):
|
||||||
variables = {}
|
variables = {}
|
||||||
for variable in await family.list('all'):
|
for variable in await family.list('all'):
|
||||||
if await variable.option.isoptiondescription() and await variable.option.isleadership():
|
if await variable.option.isoptiondescription():
|
||||||
for idx, suboption in enumerate(await variable.list('all')):
|
if await variable.option.isleadership():
|
||||||
if idx == 0:
|
for idx, suboption in enumerate(await variable.list('all')):
|
||||||
leader = CreoleLeader(await suboption.value.get())
|
if idx == 0:
|
||||||
leader_name = await suboption.option.name()
|
leader = CreoleLeader(await suboption.value.get())
|
||||||
else:
|
leader_name = await suboption.option.name()
|
||||||
await leader.add_slave(self.config,
|
else:
|
||||||
await suboption.option.name(),
|
await leader.add_follower(self.config,
|
||||||
await suboption.option.path())
|
await suboption.option.name(),
|
||||||
variables[leader_name] = leader
|
await suboption.option.path())
|
||||||
|
variables[leader_name] = leader
|
||||||
|
else:
|
||||||
|
subfamilies = await self.load_eole_variables(await variable.option.name(),
|
||||||
|
variable,
|
||||||
|
)
|
||||||
|
variables[await variable.option.name()] = subfamilies
|
||||||
else:
|
else:
|
||||||
variables[await variable.option.name()] = await variable.value.get()
|
variables[await variable.option.name()] = await variable.value.get()
|
||||||
families[await family.option.name()] = CreoleExtra(variables)
|
families[await family.option.name()] = CreoleExtra(variables)
|
||||||
self.creole_variables_dict[namespace] = CreoleExtra(families)
|
return CreoleExtra(families)
|
||||||
|
|
||||||
def patch_template(self,
|
def patch_template(self,
|
||||||
filename: str):
|
filename: str):
|
||||||
|
@ -342,6 +309,8 @@ class CreoleTemplateEngine:
|
||||||
self.patch_template(filename)
|
self.patch_template(filename)
|
||||||
|
|
||||||
def process(self,
|
def process(self,
|
||||||
|
source: str,
|
||||||
|
true_destfilename: str,
|
||||||
destfilename: str,
|
destfilename: str,
|
||||||
filevar: Dict,
|
filevar: Dict,
|
||||||
variable: Any):
|
variable: Any):
|
||||||
|
@ -350,12 +319,12 @@ class CreoleTemplateEngine:
|
||||||
# full path of the destination file
|
# full path of the destination file
|
||||||
log.info(_(f"Cheetah processing: '{destfilename}'"))
|
log.info(_(f"Cheetah processing: '{destfilename}'"))
|
||||||
try:
|
try:
|
||||||
cheetah_template = CheetahTemplate(join(self.tmp_dir,
|
cheetah_template = CheetahTemplate(source,
|
||||||
filevar['source']),
|
self.rougail_variables_dict,
|
||||||
self.creole_variables_dict,
|
|
||||||
self.eosfunc,
|
self.eosfunc,
|
||||||
destfilename,
|
true_destfilename,
|
||||||
variable)
|
variable,
|
||||||
|
)
|
||||||
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]
|
||||||
|
@ -368,51 +337,53 @@ class CreoleTemplateEngine:
|
||||||
|
|
||||||
def instance_file(self,
|
def instance_file(self,
|
||||||
filevar: Dict,
|
filevar: Dict,
|
||||||
systemd_rights: list) -> None:
|
service_name: str) -> None:
|
||||||
"""Run templatisation on one file
|
"""Run templatisation on one file
|
||||||
"""
|
"""
|
||||||
log.info(_("Instantiating file '{filename}'"))
|
log.info(_("Instantiating file '{filename}'"))
|
||||||
filenames = filevar['name']
|
|
||||||
if 'variable' in filevar:
|
if 'variable' in filevar:
|
||||||
variable = filevar['variable']
|
variable = filevar['variable']
|
||||||
else:
|
else:
|
||||||
variable = None
|
variable = None
|
||||||
|
filenames = filevar['name']
|
||||||
if not isinstance(filenames, list):
|
if not isinstance(filenames, list):
|
||||||
filenames = [filenames]
|
filenames = [filenames]
|
||||||
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,
|
destfilename = join(self.dest_dir, filename[1:])
|
||||||
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
|
||||||
self.process(destfilename,
|
source = join(self.tmp_dir, filevar['source'])
|
||||||
filevar,
|
if filevar['templating']:
|
||||||
var)
|
self.process(source,
|
||||||
systemd_rights.append(f'C {filename} {filevar["mode"]} {filevar["owner"]} {filevar["group"]} - -')
|
filename,
|
||||||
systemd_rights.append(f'z {filename} - - - - -')
|
destfilename,
|
||||||
|
filevar,
|
||||||
|
var)
|
||||||
|
else:
|
||||||
|
copy(source, destfilename)
|
||||||
|
|
||||||
async def instance_files(self) -> None:
|
async def instance_files(self) -> None:
|
||||||
"""Run templatisation on all files
|
"""Run templatisation on all files
|
||||||
"""
|
"""
|
||||||
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 in ['services', 'actions']:
|
if namespace == variable_namespace:
|
||||||
continue
|
await self.load_eole_variables_rougail(option)
|
||||||
elif namespace == 'creole':
|
|
||||||
await self.load_eole_variables_creole(option)
|
|
||||||
else:
|
else:
|
||||||
await self.load_eole_variables(namespace,
|
families = await self.load_eole_variables(namespace,
|
||||||
option)
|
option)
|
||||||
|
self.rougail_variables_dict[namespace] = families
|
||||||
for template in listdir(self.distrib_dir):
|
for template in listdir(self.distrib_dir):
|
||||||
self.prepare_template(join(self.distrib_dir, template))
|
self.prepare_template(join(self.distrib_dir, template))
|
||||||
systemd_rights = []
|
|
||||||
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()
|
||||||
for fills in await service_obj.list('all'):
|
for fills in await service_obj.list('all'):
|
||||||
if await fills.option.name() == 'files':
|
if await fills.option.name() in ['files', 'overrides']:
|
||||||
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']
|
||||||
|
@ -421,23 +392,22 @@ class CreoleTemplateEngine:
|
||||||
raise FileNotFound(_(f"File {distib_file} 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,
|
||||||
systemd_rights)
|
service_name,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
log.debug(_("Instantiation of file '{filename}' disabled"))
|
log.debug(_("Instantiation of file '{filename}' disabled"))
|
||||||
|
|
||||||
with open(join(self.dest_dir, 'rougail.conf'), 'w') as fh:
|
|
||||||
fh.write('\n'.join(systemd_rights))
|
|
||||||
fh.write('\n')
|
|
||||||
|
|
||||||
|
|
||||||
async def generate(config: Config,
|
async def generate(config: Config,
|
||||||
eosfunc_file: str,
|
eosfunc_file: str,
|
||||||
distrib_dir: str,
|
distrib_dir: str,
|
||||||
tmp_dir: str,
|
tmp_dir: str,
|
||||||
dest_dir: str) -> None:
|
dest_dir: str,
|
||||||
|
) -> None:
|
||||||
engine = CreoleTemplateEngine(config,
|
engine = CreoleTemplateEngine(config,
|
||||||
eosfunc_file,
|
eosfunc_file,
|
||||||
distrib_dir,
|
distrib_dir,
|
||||||
tmp_dir,
|
tmp_dir,
|
||||||
dest_dir)
|
dest_dir,
|
||||||
|
)
|
||||||
await engine.instance_files()
|
await engine.instance_files()
|
||||||
|
|
10
src/rougail/tiramisu.py
Normal file
10
src/rougail/tiramisu.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from tiramisu import DynOptionDescription
|
||||||
|
from .utils import normalize_family
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertDynOptionDescription(DynOptionDescription):
|
||||||
|
def convert_suffix_to_path(self, suffix):
|
||||||
|
if not isinstance(suffix, str):
|
||||||
|
suffix = str(suffix)
|
||||||
|
return normalize_family(suffix,
|
||||||
|
check_name=False)
|
503
src/rougail/tiramisureflector.py
Normal file
503
src/rougail/tiramisureflector.py
Normal file
|
@ -0,0 +1,503 @@
|
||||||
|
"""loader
|
||||||
|
flattened XML specific
|
||||||
|
"""
|
||||||
|
from os.path import isfile
|
||||||
|
from lxml.etree import DTD
|
||||||
|
|
||||||
|
from .config import dtdfilename, variable_namespace
|
||||||
|
from .i18n import _
|
||||||
|
from .error import LoaderError
|
||||||
|
from .annotator import ERASED_ATTRIBUTES
|
||||||
|
|
||||||
|
|
||||||
|
FUNC_TO_DICT = ['valid_not_equal']
|
||||||
|
FORCE_INFORMATIONS = ['help', 'test', 'separator', 'manage']
|
||||||
|
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:
|
||||||
|
def __init__(self,
|
||||||
|
xmlroot,
|
||||||
|
funcs_path,
|
||||||
|
):
|
||||||
|
self.storage = ElementStorage()
|
||||||
|
self.storage.text = ["from tiramisu import *",
|
||||||
|
"from rougail.tiramisu import ConvertDynOptionDescription",
|
||||||
|
"import imp",
|
||||||
|
f"func = imp.load_source('func', '{funcs_path}')",
|
||||||
|
]
|
||||||
|
self.make_tiramisu_objects(xmlroot)
|
||||||
|
# parse object
|
||||||
|
self.storage.get('.').get()
|
||||||
|
|
||||||
|
def make_tiramisu_objects(self,
|
||||||
|
xmlroot,
|
||||||
|
):
|
||||||
|
family = self.get_root_family()
|
||||||
|
for xmlelt in self.reorder_family(xmlroot):
|
||||||
|
self.iter_family(xmlelt,
|
||||||
|
family,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_root_family(self):
|
||||||
|
family = Family(BaseElt('baseoption',
|
||||||
|
'baseoption',
|
||||||
|
),
|
||||||
|
self.storage,
|
||||||
|
False,
|
||||||
|
'.',
|
||||||
|
)
|
||||||
|
return family
|
||||||
|
|
||||||
|
def reorder_family(self, xmlroot):
|
||||||
|
# variable_namespace family has to be loaded before any other family
|
||||||
|
# because `extra` family could use `variable_namespace` variables.
|
||||||
|
if hasattr(xmlroot, 'variables'):
|
||||||
|
if variable_namespace in xmlroot.variables:
|
||||||
|
yield xmlroot.variables[variable_namespace]
|
||||||
|
for xmlelt, value in xmlroot.variables.items():
|
||||||
|
if xmlelt != variable_namespace:
|
||||||
|
yield value
|
||||||
|
if hasattr(xmlroot, 'services'):
|
||||||
|
yield xmlroot.services
|
||||||
|
|
||||||
|
def get_attributes(self, space): # pylint: disable=R0201
|
||||||
|
for attr in dir(space):
|
||||||
|
if not attr.startswith('_') and attr not in ERASED_ATTRIBUTES:
|
||||||
|
yield attr
|
||||||
|
|
||||||
|
def get_children(self,
|
||||||
|
space,
|
||||||
|
):
|
||||||
|
for tag in self.get_attributes(space):
|
||||||
|
children = getattr(space, tag)
|
||||||
|
if children.__class__.__name__ == 'Family':
|
||||||
|
children = [children]
|
||||||
|
if isinstance(children, dict):
|
||||||
|
children = list(children.values())
|
||||||
|
if isinstance(children, list):
|
||||||
|
yield tag, children
|
||||||
|
|
||||||
|
def iter_family(self,
|
||||||
|
child,
|
||||||
|
family,
|
||||||
|
subpath,
|
||||||
|
):
|
||||||
|
tag = child.__class__.__name__
|
||||||
|
if tag == 'Variable':
|
||||||
|
function = self.populate_variable
|
||||||
|
elif tag == 'Property':
|
||||||
|
# property already imported with family
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
function = self.populate_family
|
||||||
|
#else:
|
||||||
|
# raise Exception('unknown tag {}'.format(child.tag))
|
||||||
|
function(family,
|
||||||
|
child,
|
||||||
|
subpath,
|
||||||
|
)
|
||||||
|
|
||||||
|
def populate_family(self,
|
||||||
|
parent_family,
|
||||||
|
elt,
|
||||||
|
subpath,
|
||||||
|
):
|
||||||
|
path = self.build_path(subpath,
|
||||||
|
elt,
|
||||||
|
)
|
||||||
|
tag = elt.__class__.__name__
|
||||||
|
family = Family(elt,
|
||||||
|
self.storage,
|
||||||
|
tag == 'Leadership',
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
parent_family.add(family)
|
||||||
|
for tag, children in self.get_children(elt):
|
||||||
|
for child in children:
|
||||||
|
self.iter_family(child,
|
||||||
|
family,
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
|
||||||
|
def populate_variable(self,
|
||||||
|
family,
|
||||||
|
elt,
|
||||||
|
subpath,
|
||||||
|
):
|
||||||
|
is_follower = False
|
||||||
|
is_leader = False
|
||||||
|
if family.is_leader:
|
||||||
|
if elt.name != family.elt.name:
|
||||||
|
is_follower = True
|
||||||
|
else:
|
||||||
|
is_leader = True
|
||||||
|
family.add(Variable(elt,
|
||||||
|
self.storage,
|
||||||
|
is_follower,
|
||||||
|
is_leader,
|
||||||
|
self.build_path(subpath,
|
||||||
|
elt,
|
||||||
|
)
|
||||||
|
))
|
||||||
|
|
||||||
|
def build_path(self,
|
||||||
|
subpath,
|
||||||
|
elt,
|
||||||
|
):
|
||||||
|
if subpath is None:
|
||||||
|
return elt.name
|
||||||
|
return subpath + '.' + elt.name
|
||||||
|
|
||||||
|
def get_text(self):
|
||||||
|
return '\n'.join(self.storage.get('.').get_text())
|
||||||
|
|
||||||
|
|
||||||
|
class BaseElt:
|
||||||
|
def __init__(self,
|
||||||
|
name,
|
||||||
|
doc,
|
||||||
|
):
|
||||||
|
self.name = name
|
||||||
|
self.doc = doc
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter([])
|
||||||
|
|
||||||
|
|
||||||
|
class ElementStorage:
|
||||||
|
def __init__(self,
|
||||||
|
):
|
||||||
|
self.paths = {}
|
||||||
|
self.text = []
|
||||||
|
self.index = 0
|
||||||
|
|
||||||
|
def add(self, path, elt):
|
||||||
|
self.paths[path] = (elt, self.index)
|
||||||
|
self.index += 1
|
||||||
|
|
||||||
|
def get(self, path):
|
||||||
|
if path not in self.paths or self.paths[path][0] is None:
|
||||||
|
raise LoaderError(_('there is no element for path {}').format(path))
|
||||||
|
return self.paths[path][0]
|
||||||
|
|
||||||
|
def get_name(self, path):
|
||||||
|
if path not in self.paths:
|
||||||
|
raise LoaderError(_('there is no element for index {}').format(path))
|
||||||
|
return f'option_{self.paths[path][1]}'
|
||||||
|
|
||||||
|
|
||||||
|
class Common:
|
||||||
|
def __init__(self,
|
||||||
|
elt,
|
||||||
|
storage,
|
||||||
|
is_leader,
|
||||||
|
path,
|
||||||
|
):
|
||||||
|
self.option_name = None
|
||||||
|
self.path = path
|
||||||
|
self.attrib = {}
|
||||||
|
self.informations = {}
|
||||||
|
self.storage = storage
|
||||||
|
self.is_leader = is_leader
|
||||||
|
self.storage.add(self.path, self)
|
||||||
|
|
||||||
|
def populate_properties(self, child):
|
||||||
|
if child.type == 'calculation':
|
||||||
|
action = f"ParamValue('{child.name}')"
|
||||||
|
option_name = self.storage.get(child.source).get()
|
||||||
|
kwargs = f"'condition': ParamOption({option_name}, todict=True), 'expected': ParamValue('{child.expected}')"
|
||||||
|
if child.inverse:
|
||||||
|
kwargs += ", 'reverse_condition': ParamValue(True)"
|
||||||
|
prop = 'Calculation(calc_value, Params(' + action + ', kwargs={' + kwargs + '}))'
|
||||||
|
else:
|
||||||
|
prop = "'" + child.text + "'"
|
||||||
|
if self.attrib['properties']:
|
||||||
|
self.attrib['properties'] += ', '
|
||||||
|
self.attrib['properties'] += prop
|
||||||
|
|
||||||
|
def get_attrib(self, attrib):
|
||||||
|
ret_list = []
|
||||||
|
for key, value in self.attrib.items():
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
if key == 'properties':
|
||||||
|
if not self.attrib[key]:
|
||||||
|
continue
|
||||||
|
value = "frozenset({" + self.attrib[key] + "})"
|
||||||
|
elif key in ['default', 'multi', 'suffixes', 'validators']:
|
||||||
|
value = self.attrib[key]
|
||||||
|
elif isinstance(value, str) and key != 'opt' and not value.startswith('['):
|
||||||
|
value = "'" + value.replace("'", "\\\'") + "'"
|
||||||
|
ret_list.append(f'{key}={value}')
|
||||||
|
return ', '.join(ret_list)
|
||||||
|
|
||||||
|
def populate_informations(self):
|
||||||
|
for key, value in self.informations.items():
|
||||||
|
if isinstance(value, str):
|
||||||
|
value = '"' + value.replace('"', '\"') + '"'
|
||||||
|
self.storage.text.append(f'{self.option_name}.impl_set_information("{key}", {value})')
|
||||||
|
|
||||||
|
def get_text(self,
|
||||||
|
):
|
||||||
|
return self.storage.text
|
||||||
|
|
||||||
|
def get_attributes(self, space): # pylint: disable=R0201
|
||||||
|
attributes = dir(space)
|
||||||
|
for attr in ATTRIBUTES_ORDER:
|
||||||
|
if attr in attributes:
|
||||||
|
yield attr
|
||||||
|
for attr in dir(space):
|
||||||
|
if attr not in ATTRIBUTES_ORDER:
|
||||||
|
if not attr.startswith('_') and attr not in ERASED_ATTRIBUTES:
|
||||||
|
value = getattr(space, attr)
|
||||||
|
if not isinstance(value, (list, dict)) and not value.__class__.__name__ == 'Family':
|
||||||
|
yield attr
|
||||||
|
|
||||||
|
def get_children(self,
|
||||||
|
space,
|
||||||
|
):
|
||||||
|
for attr in dir(space):
|
||||||
|
if not attr.startswith('_') and attr not in ERASED_ATTRIBUTES:
|
||||||
|
value = getattr(space, attr)
|
||||||
|
if isinstance(value, (list, dict)):
|
||||||
|
children = getattr(space, attr)
|
||||||
|
if children.__class__.__name__ == 'Family':
|
||||||
|
children = [children]
|
||||||
|
if isinstance(children, dict):
|
||||||
|
children = list(children.values())
|
||||||
|
if children and isinstance(children, list):
|
||||||
|
yield attr, children
|
||||||
|
|
||||||
|
|
||||||
|
class Variable(Common):
|
||||||
|
def __init__(self,
|
||||||
|
elt,
|
||||||
|
storage,
|
||||||
|
is_follower,
|
||||||
|
is_leader,
|
||||||
|
path,
|
||||||
|
):
|
||||||
|
super().__init__(elt,
|
||||||
|
storage,
|
||||||
|
is_leader,
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
self.is_follower = is_follower
|
||||||
|
convert_option = CONVERT_OPTION[elt.type]
|
||||||
|
del elt.type
|
||||||
|
self.object_type = convert_option['opttype']
|
||||||
|
self.attrib.update(convert_option.get('initkwargs', {}))
|
||||||
|
if self.object_type != 'SymLinkOption':
|
||||||
|
self.attrib['properties'] = []
|
||||||
|
self.attrib['validators'] = []
|
||||||
|
self.elt = elt
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
if self.option_name is None:
|
||||||
|
self.populate_attrib()
|
||||||
|
if self.object_type == 'SymLinkOption':
|
||||||
|
self.attrib['opt'] = self.storage.get(self.attrib['opt']).get()
|
||||||
|
else:
|
||||||
|
self.parse_children()
|
||||||
|
attrib = self.get_attrib(self.attrib)
|
||||||
|
self.option_name = self.storage.get_name(self.path)
|
||||||
|
self.storage.text.append(f'{self.option_name} = {self.object_type}({attrib})')
|
||||||
|
self.populate_informations()
|
||||||
|
return self.option_name
|
||||||
|
|
||||||
|
def populate_attrib(self):
|
||||||
|
for key in self.get_attributes(self.elt):
|
||||||
|
value = getattr(self.elt, key)
|
||||||
|
if key in FORCE_INFORMATIONS:
|
||||||
|
if key == 'test':
|
||||||
|
value = value.split(',')
|
||||||
|
if self.object_type == 'IntOption':
|
||||||
|
value = [int(v) for v in value]
|
||||||
|
self.informations[key] = value
|
||||||
|
else:
|
||||||
|
self.attrib[key] = value
|
||||||
|
|
||||||
|
def parse_children(self):
|
||||||
|
if not 'default' in self.attrib or self.attrib['multi']:
|
||||||
|
self.attrib['default'] = []
|
||||||
|
if self.attrib['multi'] == 'submulti' and self.is_follower:
|
||||||
|
self.attrib['default_multi'] = []
|
||||||
|
choices = []
|
||||||
|
if 'properties' in self.attrib:
|
||||||
|
if self.attrib['properties']:
|
||||||
|
self.attrib['properties'] = "'" + "', '".join(sorted(list(self.attrib['properties']))) + "'"
|
||||||
|
else:
|
||||||
|
self.attrib['properties'] = ''
|
||||||
|
for tag, children in self.get_children(self.elt):
|
||||||
|
for child in children:
|
||||||
|
if tag == 'property':
|
||||||
|
self.populate_properties(child)
|
||||||
|
elif tag == 'value':
|
||||||
|
if child.type == 'calculation':
|
||||||
|
self.attrib['default'] = self.calculation_value(child, [])
|
||||||
|
else:
|
||||||
|
self.populate_value(child)
|
||||||
|
elif tag == 'check':
|
||||||
|
self.attrib['validators'].append(self.calculation_value(child, ['ParamSelfOption()']))
|
||||||
|
elif tag == 'choice':
|
||||||
|
choices.append(child.name)
|
||||||
|
if choices:
|
||||||
|
self.attrib['values'] = tuple(choices)
|
||||||
|
if self.attrib['default'] == []:
|
||||||
|
del self.attrib['default']
|
||||||
|
elif not self.attrib['multi'] and isinstance(self.attrib['default'], list):
|
||||||
|
self.attrib['default'] = self.attrib['default'][-1]
|
||||||
|
if self.attrib['validators'] == []:
|
||||||
|
del self.attrib['validators']
|
||||||
|
else:
|
||||||
|
self.attrib['validators'] = '[' + ', '.join(self.attrib['validators']) + ']'
|
||||||
|
|
||||||
|
def calculation_value(self, child, args):
|
||||||
|
kwargs = []
|
||||||
|
if hasattr(child, 'name'):
|
||||||
|
# has parameters
|
||||||
|
function = child.name
|
||||||
|
if hasattr(child, 'param'):
|
||||||
|
for param in child.param:
|
||||||
|
value = self.populate_param(param)
|
||||||
|
if not hasattr(param, 'name'):
|
||||||
|
args.append(str(value))
|
||||||
|
else:
|
||||||
|
kwargs.append(f"'{param.name}': " + value)
|
||||||
|
else:
|
||||||
|
# function without any parameter
|
||||||
|
function = child.text.strip()
|
||||||
|
ret = f"Calculation(func.{function}, Params((" + ', '.join(args) + "), kwargs=" + "{" + ', '.join(kwargs) + "})"
|
||||||
|
if hasattr(child, 'warnings_only'):
|
||||||
|
ret += f', warnings_only={child.warnings_only}'
|
||||||
|
return ret + ')'
|
||||||
|
|
||||||
|
def populate_param(self,
|
||||||
|
param,
|
||||||
|
):
|
||||||
|
if param.type == 'string':
|
||||||
|
return f'ParamValue("{param.text}")'
|
||||||
|
elif param.type == 'number':
|
||||||
|
return f'ParamValue({param.text})'
|
||||||
|
elif param.type == 'variable':
|
||||||
|
value = {'option': param.text,
|
||||||
|
'notraisepropertyerror': param.notraisepropertyerror,
|
||||||
|
'todict': param.text in FUNC_TO_DICT,
|
||||||
|
}
|
||||||
|
if hasattr(param, 'suffix'):
|
||||||
|
value['suffix'] = param.suffix
|
||||||
|
return self.build_param(value)
|
||||||
|
raise LoaderError(_('unknown param type {}').format(param.type))
|
||||||
|
|
||||||
|
def populate_value(self,
|
||||||
|
child,
|
||||||
|
):
|
||||||
|
value = child.name
|
||||||
|
if self.attrib['multi'] == 'submulti':
|
||||||
|
self.attrib['default_multi'].append(value)
|
||||||
|
elif self.is_follower:
|
||||||
|
self.attrib['default_multi'] = value
|
||||||
|
elif self.attrib['multi']:
|
||||||
|
self.attrib['default'].append(value)
|
||||||
|
if not self.is_leader:
|
||||||
|
self.attrib['default_multi'] = value
|
||||||
|
elif isinstance(value, int):
|
||||||
|
self.attrib['default'].append(value)
|
||||||
|
else:
|
||||||
|
self.attrib['default'].append("'" + value + "'")
|
||||||
|
|
||||||
|
def build_param(self,
|
||||||
|
param,
|
||||||
|
):
|
||||||
|
option_name = self.storage.get(param['option']).get()
|
||||||
|
if 'suffix' in param:
|
||||||
|
family = '.'.join(param['option'].split('.')[:-1])
|
||||||
|
family_option = self.storage.get_name(family)
|
||||||
|
return f"ParamDynOption({option_name}, '{param['suffix']}', {family_option}, notraisepropertyerror={param['notraisepropertyerror']}, todict={param['todict']})"
|
||||||
|
return f"ParamOption({option_name}, notraisepropertyerror={param['notraisepropertyerror']}, todict={param['todict']})"
|
||||||
|
|
||||||
|
|
||||||
|
class Family(Common):
|
||||||
|
def __init__(self,
|
||||||
|
elt,
|
||||||
|
storage,
|
||||||
|
is_leader,
|
||||||
|
path,
|
||||||
|
):
|
||||||
|
super().__init__(elt,
|
||||||
|
storage,
|
||||||
|
is_leader,
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
self.children = []
|
||||||
|
self.elt = elt
|
||||||
|
|
||||||
|
def add(self, child):
|
||||||
|
self.children.append(child)
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
if not self.option_name:
|
||||||
|
self.populate_attrib()
|
||||||
|
self.parse_children()
|
||||||
|
self.option_name = self.storage.get_name(self.path)
|
||||||
|
object_name = self.get_object_name()
|
||||||
|
attrib = self.get_attrib(self.attrib) + ', children=[' + ', '.join([child.get() for child in self.children]) + ']'
|
||||||
|
self.storage.text.append(f'{self.option_name} = {object_name}({attrib})')
|
||||||
|
self.populate_informations()
|
||||||
|
return self.option_name
|
||||||
|
|
||||||
|
def populate_attrib(self):
|
||||||
|
for key in self.get_attributes(self.elt):
|
||||||
|
value = getattr(self.elt, key)
|
||||||
|
if key in FORCE_INFORMATIONS:
|
||||||
|
self.informations[key] = value
|
||||||
|
elif key == 'dynamic':
|
||||||
|
dynamic = self.storage.get(value).get()
|
||||||
|
self.attrib['suffixes'] = f"Calculation(func.calc_value, Params((ParamOption({dynamic}))))"
|
||||||
|
else:
|
||||||
|
self.attrib[key] = value
|
||||||
|
|
||||||
|
def parse_children(self):
|
||||||
|
if 'properties' in self.attrib:
|
||||||
|
self.attrib['properties'] = "'" + "', '".join(sorted(list(self.attrib['properties']))) + "'"
|
||||||
|
if hasattr(self.elt, 'property'):
|
||||||
|
#self.attrib['properties'] = ''
|
||||||
|
for child in self.elt.property:
|
||||||
|
self.populate_properties(child)
|
||||||
|
if not self.attrib['properties']:
|
||||||
|
del self.attrib['properties']
|
||||||
|
|
||||||
|
def get_object_name(self):
|
||||||
|
if 'suffixes' in self.attrib:
|
||||||
|
return 'ConvertDynOptionDescription'
|
||||||
|
elif not self.is_leader:
|
||||||
|
return 'OptionDescription'
|
||||||
|
return 'Leadership'
|
|
@ -6,9 +6,8 @@ from os import listdir
|
||||||
from lxml.etree import DTD, parse, tostring # , XMLParser
|
from lxml.etree import DTD, parse, tostring # , XMLParser
|
||||||
|
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .error import CreoleDictConsistencyError
|
from .error import DictConsistencyError
|
||||||
|
|
||||||
HIGH_COMPATIBILITY = True
|
|
||||||
|
|
||||||
class XMLReflector(object):
|
class XMLReflector(object):
|
||||||
"""Helper class for loading the Creole XML file,
|
"""Helper class for loading the Creole XML file,
|
||||||
|
@ -35,58 +34,53 @@ class XMLReflector(object):
|
||||||
|
|
||||||
:returns: the root element tree object
|
:returns: the root element tree object
|
||||||
"""
|
"""
|
||||||
# FIXME zephir2
|
|
||||||
# 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 CreoleDictConsistencyError(_("not a valid xml file: {}").format(xmlfile))
|
raise DictConsistencyError(_("not a valid xml file: {}").format(xmlfile))
|
||||||
return document.getroot()
|
return document.getroot()
|
||||||
|
|
||||||
def load_xml_from_folders(self, xmlfolders, from_zephir):
|
def load_xml_from_folders(self, xmlfolders):
|
||||||
"""Loads all the XML files located in the xmlfolders' list
|
"""Loads all the XML files located in the xmlfolders' list
|
||||||
|
|
||||||
:param xmlfolders: list of full folder's name
|
:param xmlfolders: list of full folder's name
|
||||||
"""
|
"""
|
||||||
documents = []
|
documents = []
|
||||||
if from_zephir:
|
if not isinstance(xmlfolders, list):
|
||||||
for idx, xmlfile in enumerate(xmlfolders):
|
xmlfolders = [xmlfolders]
|
||||||
documents.append(('generate_{}'.format(idx), self.parse_xmlfile(xmlfile, from_zephir=from_zephir)))
|
for xmlfolder in xmlfolders:
|
||||||
else:
|
if isinstance(xmlfolder, list) or isinstance(xmlfolder, tuple):
|
||||||
if not isinstance(xmlfolders, list):
|
# directory group : collect files from each
|
||||||
xmlfolders = [xmlfolders]
|
# directory and sort them before loading
|
||||||
for xmlfolder in xmlfolders:
|
group_files = []
|
||||||
if isinstance(xmlfolder, list) or isinstance(xmlfolder, tuple):
|
for idx, subdir in enumerate(xmlfolder):
|
||||||
# directory group : collect files from each
|
if isdir(subdir):
|
||||||
# directory and sort them before loading
|
for filename in listdir(subdir):
|
||||||
group_files = []
|
group_files.append((filename, idx, subdir))
|
||||||
for idx, subdir in enumerate(xmlfolder):
|
else:
|
||||||
if isdir(subdir):
|
group_files.append(basename(subdir), idx, dirname(subdir))
|
||||||
for filename in listdir(subdir):
|
def sort_group(file1, file2):
|
||||||
group_files.append((filename, idx, subdir))
|
if file1[0] == file2[0]:
|
||||||
else:
|
# sort by initial xmlfolder order if same name
|
||||||
group_files.append(basename(subdir), idx, dirname(subdir))
|
return file1[1].__cmp__(file2[1])
|
||||||
def sort_group(file1, file2):
|
# sort by filename
|
||||||
if file1[0] == file2[0]:
|
elif file1[0] > file2[0]:
|
||||||
# sort by initial xmlfolder order if same name
|
return 1
|
||||||
return file1[1].__cmp__(file2[1])
|
else:
|
||||||
# sort by filename
|
return -1
|
||||||
elif file1[0] > file2[0]:
|
group_files.sort(sort_group)
|
||||||
return 1
|
filenames = [join(f[2], f[0]) for f in group_files]
|
||||||
else:
|
elif isdir(xmlfolder):
|
||||||
return -1
|
filenames = []
|
||||||
group_files.sort(sort_group)
|
for filename in listdir(xmlfolder):
|
||||||
filenames = [join(f[2], f[0]) for f in group_files]
|
filenames.append(join(xmlfolder, filename))
|
||||||
elif isdir(xmlfolder):
|
filenames.sort()
|
||||||
filenames = []
|
else:
|
||||||
for filename in listdir(xmlfolder):
|
filenames = [xmlfolder]
|
||||||
filenames.append(join(xmlfolder, filename))
|
for xmlfile in filenames:
|
||||||
filenames.sort()
|
if xmlfile.endswith('.xml'):
|
||||||
else:
|
#xmlfile_path = join(xmlfolder, xmlfile)
|
||||||
filenames = [xmlfolder]
|
documents.append((xmlfile, self.parse_xmlfile(xmlfile)))
|
||||||
for xmlfile in filenames:
|
|
||||||
if xmlfile.endswith('.xml'):
|
|
||||||
#xmlfile_path = join(xmlfolder, xmlfile)
|
|
||||||
documents.append((xmlfile, self.parse_xmlfile(xmlfile)))
|
|
||||||
return documents
|
return documents
|
||||||
|
|
||||||
def save_xmlfile(self, xmlfilename, xml): # pylint: disable=R0201
|
def save_xmlfile(self, xmlfilename, xml): # pylint: disable=R0201
|
||||||
|
|
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
|
@ -24,10 +24,6 @@ def get_mount_point_device(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def valid_entier(*args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def valid_differ(*args, **kwargs):
|
def valid_differ(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -59,3 +55,7 @@ def cdrom_minormajor(*args, **kwargs):
|
||||||
|
|
||||||
def device_type(*args, **kwargs):
|
def device_type(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def calc_list(*args, **kwargs):
|
||||||
|
return []
|
||||||
|
|
0
tests/flattener_dicos/00empty/__init__.py
Normal file
0
tests/flattener_dicos/00empty/__init__.py
Normal file
|
@ -1,8 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family name="services">
|
|
||||||
<family name="service0" doc="tata">
|
|
||||||
<property>basic</property>
|
|
||||||
</family>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/00empty/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/00empty/tiramisu/__init__.py
Normal file
8
tests/flattener_dicos/00empty/tiramisu/base.py
Normal file
8
tests/flattener_dicos/00empty/tiramisu/base.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
option_2 = OptionDescription(name='tata', doc='tata', children=[])
|
||||||
|
option_2.impl_set_information("manage", True)
|
||||||
|
option_1 = OptionDescription(name='services', doc='services', properties=frozenset({'hidden'}), children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -1,8 +1,6 @@
|
||||||
<?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">
|
<variable name="mode_conteneur_actif" type="oui/non" description="No change" auto_freeze="True">
|
||||||
|
|
0
tests/flattener_dicos/00load_autofreeze/__init__.py
Normal file
0
tests/flattener_dicos/00load_autofreeze/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": "non", "creole.general.module_instancie": "non"}
|
{"rougail.general.mode_conteneur_actif": "non", "rougail.general.module_instancie": "non"}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>basic</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<property>auto_freeze</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>basic</property>
|
|
||||||
<property expected="oui" inverse="True" source="creole.general.module_instancie" type="calculation">auto_frozen</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="module_instancie" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
9
tests/flattener_dicos/00load_autofreeze/tiramisu/base.py
Normal file
9
tests/flattener_dicos/00load_autofreeze/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
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_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_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": "non", "creole.general.module_instancie": "non"}
|
{"rougail.general.mode_conteneur_actif": "non", "rougail.general.module_instancie": "non"}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<property>auto_freeze</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>expert</property>
|
|
||||||
<property expected="oui" inverse="True" source="creole.general.module_instancie" type="calculation">auto_frozen</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="module_instancie" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
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_2 = OptionDescription(name='general', doc='général', 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])
|
0
tests/flattener_dicos/00load_autosave/__init__.py
Normal file
0
tests/flattener_dicos/00load_autosave/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": "non"}
|
{"rougail.general.mode_conteneur_actif": "non"}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>basic</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>basic</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
8
tests/flattener_dicos/00load_autosave/tiramisu/base.py
Normal file
8
tests/flattener_dicos/00load_autosave/tiramisu/base.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/00load_autosaveexpert/__init__.py
Normal file
0
tests/flattener_dicos/00load_autosaveexpert/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": "non"}
|
{"rougail.general.mode_conteneur_actif": "non"}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>expert</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>expert</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/00load_comment/__init__.py
Normal file
0
tests/flattener_dicos/00load_comment/__init__.py
Normal file
1
tests/flattener_dicos/00load_comment/makedict/base.json
Normal file
1
tests/flattener_dicos/00load_comment/makedict/base.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"rougail.general.mode_conteneur_actif": "non"}
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
8
tests/flattener_dicos/00load_comment/tiramisu/base.py
Normal file
8
tests/flattener_dicos/00load_comment/tiramisu/base.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/00load_notype/__init__.py
Normal file
0
tests/flattener_dicos/00load_notype/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.without_type": "non"}
|
{"rougail.general.mode_conteneur_actif": "non", "rougail.general.without_type": "non"}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="without_type" multi="False" name="without_type" type="string">
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value>non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/00load_notype/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/00load_notype/tiramisu/__init__.py
Normal file
9
tests/flattener_dicos/00load_notype/tiramisu/base.py
Normal file
9
tests/flattener_dicos/00load_notype/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/00load_save/__init__.py
Normal file
0
tests/flattener_dicos/00load_save/__init__.py
Normal file
1
tests/flattener_dicos/00load_save/makedict/base.json
Normal file
1
tests/flattener_dicos/00load_save/makedict/base.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"rougail.general.mode_conteneur_actif": "non"}
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/00load_save/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/00load_save/tiramisu/__init__.py
Normal file
8
tests/flattener_dicos/00load_save/tiramisu/base.py
Normal file
8
tests/flattener_dicos/00load_save/tiramisu/base.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/00load_subfolder/__init__.py
Normal file
0
tests/flattener_dicos/00load_subfolder/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"rougail.general.mode_conteneur_actif": "non", "rougail.general.mode_conteneur_actif1": "non"}
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
9
tests/flattener_dicos/00load_subfolder/tiramisu/base.py
Normal file
9
tests/flattener_dicos/00load_subfolder/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -16,9 +16,9 @@
|
||||||
</variables>
|
</variables>
|
||||||
|
|
||||||
<constraints>
|
<constraints>
|
||||||
<auto name="calc_val" target="mode_conteneur_actif">
|
<fill name="calc_val" target="mode_conteneur_actif">
|
||||||
<param type="variable">mode_conteneur_actif1</param>
|
<param type="variable">mode_conteneur_actif1</param>
|
||||||
</auto>
|
</fill>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
|
||||||
<help/>
|
<help/>
|
||||||
|
|
0
tests/flattener_dicos/01auto_base/__init__.py
Normal file
0
tests/flattener_dicos/01auto_base/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif1": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?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="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value name="calc_val" type="calculation">
|
|
||||||
<param transitive="False" type="variable">creole.general.mode_conteneur_actif1</param>
|
|
||||||
</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/01auto_base/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/01auto_base/tiramisu/__init__.py
Normal file
9
tests/flattener_dicos/01auto_base/tiramisu/base.py
Normal file
9
tests/flattener_dicos/01auto_base/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
|
@ -16,8 +16,8 @@
|
||||||
</variables>
|
</variables>
|
||||||
|
|
||||||
<constraints>
|
<constraints>
|
||||||
<auto name="calc_val" target="mode_conteneur_actif">
|
<fill name="calc_val" target="mode_conteneur_actif">
|
||||||
</auto>
|
</fill>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
|
||||||
<help/>
|
<help/>
|
||||||
|
|
0
tests/flattener_dicos/01auto_withoutparam/__init__.py
Normal file
0
tests/flattener_dicos/01auto_withoutparam/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif1": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?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="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="calculation">calc_val</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/01base_multi/__init__.py
Normal file
0
tests/flattener_dicos/01base_multi/__init__.py
Normal file
1
tests/flattener_dicos/01base_multi/makedict/base.json
Normal file
1
tests/flattener_dicos/01base_multi/makedict/base.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"rougail.general.mode_conteneur_actif": ["non"]}
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="general" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="Redefine description" multi="True" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/01base_multi/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/01base_multi/tiramisu/__init__.py
Normal file
8
tests/flattener_dicos/01base_multi/tiramisu/base.py
Normal file
8
tests/flattener_dicos/01base_multi/tiramisu/base.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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])
|
|
@ -1,22 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<rougail>
|
|
||||||
|
|
||||||
<services/>
|
|
||||||
|
|
||||||
<variables>
|
|
||||||
<family name="general">
|
|
||||||
<variable name="mode_conteneur_actif" type="oui/non" description="Redefine description" hidden="True" submulti="True">
|
|
||||||
<value>non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</variables>
|
|
||||||
|
|
||||||
<constraints>
|
|
||||||
</constraints>
|
|
||||||
|
|
||||||
<help/>
|
|
||||||
|
|
||||||
</rougail>
|
|
||||||
<!-- vim: ts=4 sw=4 expandtab
|
|
||||||
-->
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="general" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="Redefine description" multi="submulti" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/01fill_autofreeze/__init__.py
Normal file
0
tests/flattener_dicos/01fill_autofreeze/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": null, "creole.general.mode_conteneur_actif1": "non", "creole.general.module_instancie": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non", "rougail.general.module_instancie": "non"}
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="general" name="general">
|
|
||||||
<property>basic</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<property>auto_freeze</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>basic</property>
|
|
||||||
<property expected="oui" inverse="True" source="creole.general.module_instancie" type="calculation">auto_frozen</property>
|
|
||||||
<value name="calc_val" type="calculation">
|
|
||||||
<param transitive="False" type="variable">creole.general.mode_conteneur_actif1</param>
|
|
||||||
</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="module_instancie" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
10
tests/flattener_dicos/01fill_autofreeze/tiramisu/base.py
Normal file
10
tests/flattener_dicos/01fill_autofreeze/tiramisu/base.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../eosfunc/test.py')
|
||||||
|
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_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_2 = OptionDescription(name='general', doc='general', properties=frozenset({'basic'}), children=[option_3, option_4, option_5])
|
||||||
|
option_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/01fill_autosave/__init__.py
Normal file
0
tests/flattener_dicos/01fill_autosave/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif": null, "creole.general.mode_conteneur_actif1": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="general" name="general">
|
|
||||||
<property>basic</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<property>force_store_value</property>
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>basic</property>
|
|
||||||
<value name="calc_val" type="calculation">
|
|
||||||
<param transitive="False" type="variable">creole.general.mode_conteneur_actif1</param>
|
|
||||||
</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
9
tests/flattener_dicos/01fill_autosave/tiramisu/base.py
Normal file
9
tests/flattener_dicos/01fill_autosave/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/01fill_base/__init__.py
Normal file
0
tests/flattener_dicos/01fill_base/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif1": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?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="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value name="calc_val" type="calculation">
|
|
||||||
<param transitive="False" type="variable">creole.general.mode_conteneur_actif1</param>
|
|
||||||
</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
0
tests/flattener_dicos/01fill_base/tiramisu/__init__.py
Normal file
0
tests/flattener_dicos/01fill_base/tiramisu/__init__.py
Normal file
9
tests/flattener_dicos/01fill_base/tiramisu/base.py
Normal file
9
tests/flattener_dicos/01fill_base/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/01fill_baseaccent/__init__.py
Normal file
0
tests/flattener_dicos/01fill_baseaccent/__init__.py
Normal file
|
@ -1 +1 @@
|
||||||
{"creole.general.mode_conteneur_actif1": "non"}
|
{"rougail.general.mode_conteneur_actif": null, "rougail.general.mode_conteneur_actif1": "non"}
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
|
||||||
<creole>
|
|
||||||
<family doc="" name="creole">
|
|
||||||
<family doc="Général" name="general">
|
|
||||||
<property>normal</property>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>force_default_on_freeze</property>
|
|
||||||
<property>frozen</property>
|
|
||||||
<property>hidden</property>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value name="calc_val" type="calculation">
|
|
||||||
<param transitive="False" type="variable">creole.general.mode_conteneur_actif1</param>
|
|
||||||
</value>
|
|
||||||
</variable>
|
|
||||||
<variable doc="No change" multi="False" name="mode_conteneur_actif1" type="choice">
|
|
||||||
<choice type="string">oui</choice>
|
|
||||||
<choice type="string">non</choice>
|
|
||||||
<property>mandatory</property>
|
|
||||||
<property>normal</property>
|
|
||||||
<value type="string">non</value>
|
|
||||||
</variable>
|
|
||||||
</family>
|
|
||||||
<separators/>
|
|
||||||
</family>
|
|
||||||
</creole>
|
|
9
tests/flattener_dicos/01fill_baseaccent/tiramisu/base.py
Normal file
9
tests/flattener_dicos/01fill_baseaccent/tiramisu/base.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from tiramisu import *
|
||||||
|
from rougail.tiramisu import ConvertDynOptionDescription
|
||||||
|
import imp
|
||||||
|
func = imp.load_source('func', 'tests/flattener_dicos/../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_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_1 = OptionDescription(name='rougail', doc='rougail', children=[option_2])
|
||||||
|
option_0 = OptionDescription(name='baseoption', doc='baseoption', children=[option_1])
|
0
tests/flattener_dicos/01fill_mandatory/__init__.py
Normal file
0
tests/flattener_dicos/01fill_mandatory/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue