can templating only one file

This commit is contained in:
egarette@silique.fr 2023-01-23 22:55:17 +01:00
parent f213f5777b
commit 2fd3c22db9
3 changed files with 177 additions and 67 deletions

View file

@ -292,7 +292,7 @@ class RougailBaseTemplate:
copy(join(templates_dir, filename), self.tmp_dir)
self.patch_template(filename, templates_dir)
def instance_file(self,
def _instance_file(self,
filevar: Dict,
type_: str,
service_name: str,
@ -328,7 +328,7 @@ class RougailBaseTemplate:
filename, source, true_destfilename, var = data
self.log.info(_(f'Instantiating file "{filename}"'))
if not true_destfilename.startswith('/'):
raise Exception(f'true_destfilename must starts with a / in function {func}')
raise TemplateError(f'true_destfilename must starts with a / in function {func}')
destfilename = join(self.destinations_dir, true_destfilename[1:])
makedirs(dirname(destfilename), exist_ok=True)
self.log.info(_(f"{filevar['engine']} processing: '{destfilename}'"))
@ -366,6 +366,47 @@ class RougailBaseTemplate:
is_service_namespace,
)
async def instance_file(self, template_name) -> None:
if not self.rougail_variables_dict:
await self.load_variables()
self.prepare_templates()
for service_obj in await self.config.option('services').list('all'):
service_name = await service_obj.option.description()
service_desactived = await service_obj.option('activate').value.get() is False
for fills in await service_obj.list('optiondescription'):
type_ = await fills.option.name()
for fill_obj in await fills.list('all'):
fill = await fill_obj.value.dict()
self.get_default(type_, fill, fill_obj)
await self.get_informations(type_, fill, fill_obj)
if fill['source'] != template_name:
continue
if service_desactived:
raise TemplateError(f'template {template_name} is inside a desactived service')
if 'included' in fill and fill['included'] != 'no':
raise TemplateError(f'template {template_name} is an included file')
if not fill['activate']:
raise TemplateError(f'template {template_name} is desactived')
try:
ori_dir = getcwd()
except FileNotFoundError:
ori_dir = None
chdir(self.tmp_dir)
try:
self._instance_file(fill,
type_,
service_name,
)
except Exception as err:
if ori_dir is not None:
chdir(ori_dir)
raise err from err
if ori_dir is not None:
chdir(ori_dir)
return
raise TemplateError(f'Cannot find template {template_name}')
async def instance_files(self) -> None:
"""Run templatisation on all files
"""
@ -377,11 +418,7 @@ class RougailBaseTemplate:
try:
if not self.rougail_variables_dict:
await self.load_variables()
for templates_dir in self.templates_dir:
for template in listdir(templates_dir):
self.prepare_template(template,
templates_dir,
)
self.prepare_templates()
files_to_delete = []
for included in (True, False):
for service_obj in await self.config.option('services').list('all'):
@ -393,7 +430,7 @@ class RougailBaseTemplate:
if not included:
engine = await service_obj.information.get('engine', None)
if engine:
self.instance_file({'engine': engine},
self._instance_file({'engine': engine},
'service',
service_name,
)
@ -416,7 +453,7 @@ class RougailBaseTemplate:
elif included is True:
continue
if fill['activate']:
destfilenames = self.instance_file(fill,
destfilenames = self._instance_file(fill,
type_,
service_name,
)
@ -441,6 +478,13 @@ class RougailBaseTemplate:
if ori_dir is not None:
chdir(ori_dir)
def prepare_templates(self):
for templates_dir in self.templates_dir:
for template in listdir(templates_dir):
self.prepare_template(template,
templates_dir,
)
def get_default(self,
type_: str,
dico: dict,
@ -527,7 +571,6 @@ class RougailBaseTemplate:
if not isfile(source): # pragma: no cover
raise FileNotFound(_(f'Source file "{source}" does not exist in {", ".join(self.templates_dir)}'))
tmp_file = join(self.tmp_dir, source)
#self.instance_file(fill, 'files')
if variable:
var = variable[idx]
else:

View file

@ -6,6 +6,8 @@ from lxml.etree import parse
from tiramisu import Config
from rougail import RougailConfig, RougailBaseTemplate, RougailSystemdTemplate
from rougail.error import TemplateError
from jinja2.exceptions import TemplateNotFound
template_dirs = 'tests/dictionaries'
@ -15,7 +17,7 @@ test_ok = {f for f in listdir(template_dirs) if not f.startswith('_') and isdir(
test_ok -= excludes
test_ok = list(test_ok)
test_ok.sort()
#test_ok = ['01base_file_include_content']
#test_ok = ['70service_servicelist_file']
@fixture(scope="module", params=test_ok)
@ -39,7 +41,7 @@ def find_files(dirname: str,
files.add(join(*root_file))
async def template(test_dir, filename, root, engine_name):
async def templates(test_dir, filename, root, engine_name, only_one=False):
test_dir = join(template_dirs, test_dir)
tmp_dir = join(test_dir, '..', 'tmp')
@ -55,13 +57,7 @@ async def template(test_dir, filename, root, engine_name):
funcs_file = join(template_dirs, '../eosfunc/test.py')
distrib_dir = join(test_dir, 'tmpl')
if isdir(tmp_dir):
rmtree(tmp_dir)
mkdir(tmp_dir)
dest_dir = join(test_dir, 'dest')
if isdir(dest_dir):
rmtree(dest_dir)
mkdir(dest_dir)
RougailConfig['patches_dir'] = join(test_dir, 'patches')
RougailConfig['templates_dir'] = distrib_dir
RougailConfig['tmp_dir'] = tmp_dir
@ -79,22 +75,84 @@ async def template(test_dir, filename, root, engine_name):
engine = RougailBaseTemplate(config)
else:
engine = RougailSystemdTemplate(config)
await engine.instance_files()
if not only_one:
list_templates = [None]
else:
list_templates = set()
if isdir(dest_dir):
find_files(dest_dir,
find_files(distrib_dir,
[],
list_templates,
)
for template in list_templates:
if isdir(tmp_dir):
rmtree(tmp_dir)
mkdir(tmp_dir)
if isdir(dest_dir):
rmtree(dest_dir)
mkdir(dest_dir)
if template is None:
await engine.instance_files()
list_results = set()
if isdir(join(test_dir, 'result')):
find_files(join(test_dir, 'result'),
[],
list_results,
)
else:
list_results = set()
included = False
activate = True
for service in await config.option('services').option.list('all'):
names = [await o.option.name() for o in await service.option.list('optiondescription')]
if 'files' in names:
for file in await service.option('files').list('optiondescription'):
if not await file.option('source').value.get() == template:
continue
included = await file.information.get('included', 'no') != 'no'
values = await file.option('name').value.get()
if isinstance(values, list):
for value in values:
list_results.add(value[1:])
else:
list_results.add(values[1:])
if not await file.option('activate').value.get():
activate = False
# if template is an overrides
if not list_results and 'overrides' in names:
for override in await service.option('overrides').list('optiondescription'):
if await override.option.description() == template:
return
# if template is a service
if not list_results and template == await service.option.description() and await service.information.get('engine', None):
return
#this file is include and not declared
if template.startswith('inc') and not list_results:
return
try:
await engine.instance_file(template)
except TemplateError as err:
if 'No such file or directory' in str(err):
continue
if included or not activate:
continue
raise err from err
except TemplateNotFound:
continue
assert activate, 'template should be desactivate'
assert not included, 'include file should not be templated'
# else:
# assert list_results, "should find file"
list_files = set()
if isdir(dest_dir):
find_files(dest_dir,
[],
list_files,
)
if engine_name == 'base' and 'tmpfiles.d/0rougail.conf' in list_results:
list_results.remove('tmpfiles.d/0rougail.conf')
assert list_templates == list_results, f'error with {test_dir}:'
assert list_files == list_results, f'error with {test_dir}:'
for result in list_results:
template_file = join(dest_dir, result)
assert islink(template_file) == islink(join(test_dir, 'result', result))
@ -115,14 +173,23 @@ async def template(test_dir, filename, root, engine_name):
@mark.asyncio
async def test_template(test_dir):
async def test_templates(test_dir):
for engine in ['base', 'systemd']:
not_file = join(template_dirs, test_dir, 'no_' + engine)
if isfile(not_file):
with raises(Exception) as err:
await template(test_dir, 'base', '1', engine)
await templates(test_dir, 'base', '1', engine)
else:
await template(test_dir, 'base', '1', engine)
await templates(test_dir, 'base', '1', engine)
@mark.asyncio
async def test_template(test_dir):
for engine in ['base', 'systemd']:
not_file = join(template_dirs, test_dir, 'no_' + engine)
if isfile(not_file):
continue
await templates(test_dir, 'base', '1', engine, only_one=True)
@mark.asyncio
@ -131,9 +198,9 @@ async def test_template_multi_1(test_dir):
not_file = join(template_dirs, test_dir, 'no_' + engine)
if isfile(not_file):
with raises(Exception) as err:
await template(test_dir, 'multi', '1', engine)
await templates(test_dir, 'multi', '1', engine)
else:
await template(test_dir, 'multi', '1', engine)
await templates(test_dir, 'multi', '1', engine)
@mark.asyncio
@ -142,6 +209,6 @@ async def test_template_multi_2(test_dir):
not_file = join(template_dirs, test_dir, 'no_' + engine)
if isfile(not_file):
with raises(Exception) as err:
await template(test_dir, 'multi', '1', engine)
await templates(test_dir, 'multi', '1', engine)
else:
await template(test_dir, 'multi', '1', engine)
await templates(test_dir, 'multi', '1', engine)