pylint services.py

This commit is contained in:
Emmanuel Garette 2021-01-10 21:10:19 +01:00
parent 25d4fb9db4
commit f918792419
1 changed files with 118 additions and 132 deletions

View File

@ -1,4 +1,7 @@
"""Annotate services
"""
from os.path import basename from os.path import basename
from typing import Tuple
from ..i18n import _ from ..i18n import _
from ..utils import normalize_family from ..utils import normalize_family
@ -11,13 +14,13 @@ ERASED_ATTRIBUTES = ('redefine', 'exists', 'fallback', 'optional', 'remove_check
KEY_TYPE = {'variable': 'symlink', KEY_TYPE = {'variable': 'symlink',
'SymLinkOption': 'symlink',
'PortOption': 'port', 'PortOption': 'port',
'UnicodeOption': 'string', 'UnicodeOption': 'string',
'NetworkOption': 'network', 'NetworkOption': 'network',
'NetmaskOption': 'netmask', 'NetmaskOption': 'netmask',
'URLOption': 'web_address', 'URLOption': 'web_address',
'FilenameOption': 'filename'} 'FilenameOption': 'filename',
}
class ServiceAnnotator: class ServiceAnnotator:
@ -33,14 +36,15 @@ class ServiceAnnotator:
""" """
def __init__(self, objectspace): def __init__(self, objectspace):
self.objectspace = objectspace self.objectspace = objectspace
self.convert_services() if hasattr(self.objectspace.space, 'services'):
if not hasattr(self.objectspace.space.services, 'service'):
del self.objectspace.space.services
else:
self.convert_services()
def convert_services(self): def convert_services(self):
if not hasattr(self.objectspace.space, 'services'): """convert services to variables
return """
if not hasattr(self.objectspace.space.services, 'service'):
del self.objectspace.space.services
return
self.objectspace.space.services.hidden = True self.objectspace.space.services.hidden = True
self.objectspace.space.services.name = 'services' self.objectspace.space.services.name = 'services'
self.objectspace.space.services.doc = 'services' self.objectspace.space.services.doc = 'services'
@ -54,10 +58,10 @@ class ServiceAnnotator:
continue continue
eltname = elttype + 's' eltname = elttype + 's'
path = '.'.join(['services', service_name, eltname]) path = '.'.join(['services', service_name, eltname])
family = self.gen_family(eltname, family = self._gen_family(eltname,
path, path,
service.xmlfiles, service.xmlfiles,
) )
if isinstance(values, dict): if isinstance(values, dict):
values = list(values.values()) values = list(values.values())
family.family = self.make_group_from_elts(service_name, family.family = self.make_group_from_elts(service_name,
@ -70,11 +74,87 @@ class ServiceAnnotator:
families[service_name] = new_service families[service_name] = new_service
self.objectspace.space.services.service = families self.objectspace.space.services.service = families
def gen_family(self, def make_group_from_elts(self,
name, service_name,
path, elttype,
xmlfiles elts,
): path,
):
"""Splits each objects into a group (and `OptionDescription`, in tiramisu terms)
and build elements and its attributes (the `Options` in tiramisu terms)
"""
families = []
for elt in elts:
# try to launch _update_xxxx() function
update_elt = '_update_' + elttype
if hasattr(self, update_elt):
getattr(self, update_elt)(elt,
service_name,
)
c_name, subpath = self._get_name_path(elt,
path,
)
family = self._gen_family(c_name,
subpath,
elt.xmlfiles,
)
family.variable = []
activate_path = '.'.join([subpath, 'activate'])
for key in dir(elt):
if key.startswith('_') or key.endswith('_type') or key in ERASED_ATTRIBUTES:
continue
value = getattr(elt, key)
listname = '{}list'.format(elttype)
if key == listname:
self.objectspace.list_conditions.setdefault(listname,
{}).setdefault(
value,
[]).append(activate_path)
continue
family.variable.append(self._generate_element(self._get_type(key,
elttype,
elt,
),
key,
value,
elt.xmlfiles,
f'{subpath}.{key}'
))
# FIXME ne devrait pas etre True par défaut
# devrait etre un calcule
family.variable.append(self._generate_element('boolean',
'activate',
True,
elt.xmlfiles,
activate_path,
))
families.append(family)
return families
def _get_name_path(self,
elt,
path: str,
) -> Tuple[str, str]:
# create element name, if already exists, add _xx to be uniq
if hasattr(elt, 'source'):
name = elt.source
else:
name = elt.name
idx = 0
while True:
c_name = name
if idx:
c_name += f'_{idx}'
subpath = '{}.{}'.format(path, c_name)
if not self.objectspace.paths.family_is_defined(subpath):
return c_name, subpath
idx += 1
def _gen_family(self,
name,
path,
xmlfiles
):
family = self.objectspace.family(xmlfiles) family = self.objectspace.family(xmlfiles)
family.name = normalize_family(name) family.name = normalize_family(name)
family.doc = name family.doc = name
@ -85,111 +165,25 @@ class ServiceAnnotator:
) )
return family return family
def make_group_from_elts(self,
service_name,
name,
elts,
path,
):
"""Splits each objects into a group (and `OptionDescription`, in tiramisu terms)
and build elements and its attributes (the `Options` in tiramisu terms)
"""
families = []
new_elts = self._reorder_elts(name,
elts,
)
for index, elt_info in enumerate(new_elts):
elt = elt_info['elt']
elt_name = elt_info['elt_name']
# try to launch _update_xxxx() function
update_elt = '_update_' + elt_name
if hasattr(self, update_elt):
getattr(self, update_elt)(elt,
index,
path,
service_name,
)
idx = 0
while True:
if hasattr(elt, 'source'):
c_name = elt.source
else:
c_name = elt.name
if idx:
c_name += f'_{idx}'
subpath = '{}.{}'.format(path, c_name)
if not self.objectspace.paths.family_is_defined(subpath):
break
idx += 1
family = self.gen_family(c_name,
subpath,
elt.xmlfiles,
)
family.variable = []
listname = '{}list'.format(name)
activate_path = '.'.join([subpath, 'activate'])
for key in dir(elt):
if key.startswith('_') or key.endswith('_type') or key in ERASED_ATTRIBUTES:
continue
value = getattr(elt, key)
if key == listname:
self.objectspace.list_conditions.setdefault(listname,
{}).setdefault(
value,
[]).append(activate_path)
continue
family.variable.append(self._generate_element(elt_name,
key,
value,
elt,
f'{subpath}.{key}'
))
# FIXME ne devrait pas etre True par défaut
# devrait etre un calcule
family.variable.append(self._generate_element(elt_name,
'activate',
True,
elt,
activate_path,
))
families.append(family)
return families
def _generate_element(self, def _generate_element(self,
elt_name, type_,
key, key,
value, value,
elt, xmlfiles,
path, path,
): ):
variable = self.objectspace.variable(elt.xmlfiles) variable = self.objectspace.variable(xmlfiles)
variable.name = normalize_family(key) variable.name = normalize_family(key)
variable.mode = None variable.mode = None
if key == 'name':
true_key = elt_name
else:
true_key = key
dtd_key_type = true_key + '_type'
if key == 'activate':
type_ = 'boolean'
elif hasattr(elt, dtd_key_type):
type_ = KEY_TYPE[getattr(elt, dtd_key_type)]
elif key in self.objectspace.booleans_attributs:
type_ = 'boolean'
else:
type_ = 'string'
variable.type = type_ variable.type = type_
if type_ == 'symlink': if type_ == 'symlink':
variable.opt = self.objectspace.paths.get_variable_path(value, variable.opt = self.objectspace.paths.get_variable_path(value,
'services', 'services',
) )
# variable.opt = value
variable.multi = None variable.multi = None
else: else:
variable.doc = key variable.doc = key
val = self.objectspace.value(elt.xmlfiles) val = self.objectspace.value(xmlfiles)
val.type = type_ val.type = type_
val.name = value val.name = value
variable.value = [val] variable.value = [val]
@ -201,28 +195,23 @@ class ServiceAnnotator:
) )
return variable return variable
def _reorder_elts(self, def _get_type(self,
name, key: str,
elts, elt_name: str,
): elt,
"""Reorders by index the elts ) -> str:
""" if key == 'name':
new_elts = {} dtd_key_type = elt_name + '_type'
# reorder elts by index else:
for idx, elt in enumerate(elts): dtd_key_type = key + '_type'
new_elts.setdefault(idx, []).append(elt) if key in self.objectspace.booleans_attributs:
idxes = list(new_elts.keys()) return 'boolean'
idxes.sort() if hasattr(elt, dtd_key_type):
result_elts = [] return KEY_TYPE[getattr(elt, dtd_key_type)]
for idx in idxes: return 'string'
for elt in new_elts[idx]:
result_elts.append({'elt_name': name, 'elt': elt})
return result_elts
def _update_override(self, def _update_override(self,
file_, file_,
index,
service_path,
service_name, service_name,
): ):
file_.name = f'/systemd/system/{service_name}.service.d/rougail.conf' file_.name = f'/systemd/system/{service_name}.service.d/rougail.conf'
@ -232,15 +221,11 @@ class ServiceAnnotator:
if not hasattr(file_, 'source'): if not hasattr(file_, 'source'):
file_.source = f'{service_name}.service' file_.source = f'{service_name}.service'
self._update_file(file_, self._update_file(file_,
index,
service_path,
service_name, service_name,
) )
def _update_file(self, def _update_file(self,
file_, file_,
index,
service_path,
service_name, service_name,
): ):
if not hasattr(file_, 'file_type') or file_.file_type == "UnicodeOption": if not hasattr(file_, 'file_type') or file_.file_type == "UnicodeOption":
@ -248,5 +233,6 @@ class ServiceAnnotator:
file_.source = basename(file_.name) file_.source = basename(file_.name)
elif not hasattr(file_, 'source'): elif not hasattr(file_, 'source'):
xmlfiles = self.objectspace.display_xmlfiles(file_.xmlfiles) xmlfiles = self.objectspace.display_xmlfiles(file_.xmlfiles)
raise DictConsistencyError(_(f'attribute "source" is mandatory for the file "{file_.name}" in {xmlfiles}'), 34) msg = _(f'attribute "source" is mandatory for the file "{file_.name}" '
f'"({service_name})" in {xmlfiles}')
raise DictConsistencyError(msg, 34)