Template executor checks if the template is empty now and checks original file for changes using MD5. Format 'raw' is added. fixed #10

master
Иванов Денис 4 years ago
parent f42ebc0075
commit 3834b7e168

@ -378,3 +378,6 @@ class Format():
self.CALCULATE_VERSION)
document_text = re.sub(header_pattern, '', input_text)
return header, document_text
def __bool__(self):
return bool(self._document_dictionary)

@ -0,0 +1,52 @@
# vim: fileencoding=utf-8
#
from .base_format import Format
from ..template_engine import ParametersContainer
class RawFormat(Format):
'''Класс формата raw.'''
FORMAT = 'raw'
EXECUTABLE = False
FORMAT_PARAMETERS = {'comment'}
def __init__(self, document_text: str,
template_path,
ignore_comments=False,
join_before=False,
add_header=False,
already_changed=False,
parameters=ParametersContainer()):
self.comment_symbol = parameters.comment or "#"
self._before = join_before
if add_header and not ignore_comments:
self.header, self._document_text =\
self._get_header_and_document_text(
document_text,
template_path,
already_changed=already_changed)
else:
self.header = ''
self._document_text = document_text
@property
def document_text(self):
return '{}{}'.format(self.header, self._document_text)
def join_template(self, template):
if self._before:
self._document_text = '{0}{1}{2}'.format(
template._document_text,
"" if template._document_text.
endswith("\n") else "\n",
self._document_text)
else:
self._document_text = '{0}{1}{2}'.format(
self._document_text,
"" if template._document_text.
endswith("\n") else "\n",
template._document_text)
def __bool__(self):
return bool(self.document_text)

@ -27,8 +27,6 @@ class RegexFormat(Format):
processing_methods = OrderedDict()
super().__init__(processing_methods)
self.changed_files = dict()
self._multiline_flag = parameters.multiline
self._dotall_flag = parameters.dotall
self._parsed_patch = None

@ -421,6 +421,8 @@ class ParametersProcessor:
real_path = parameter_value
# Ставим True, чтобы потом проверить этот параметр в postparse
print(f'source value {parameter_value}')
print(f'source <- {real_path}')
if not os.path.exists(real_path):
return True

@ -949,35 +949,53 @@ class TemplateExecutor:
chown = self.file_default_parameters.get('chown', False)
if template_format.EXECUTABLE or template_object.md5_matching:
# Действия при совпадении md5 из CONTENTS и md5 целевого файла.
# А также если шаблон просто исполнительный.
output_paths = [output_path]
parsed_template = template_format(template_object.template_text,
template_object.template_path,
ignore_comments=True)
# Если целевой файл защищен, а шаблон не userspace.
if template_object.protected and not template_object.is_userspace:
# Тогда также обновляем архив.
output_paths.append(template_object.archive_path)
if (not parsed_template and not template_object.parameters.source
and template_object.format_class.EXECUTABLE):
if template_object.target_type is DIR:
self._remove_directory(template_object.target_path)
shutil.copytree(input_path,
template_object.target_path)
elif template_object.target_type is FILE:
self._remove_file(template_object.target_path)
shutil.copy(input_path,
template_object.template_path)
if chown:
self._chown_file(template_object.target_path, chown)
if template_object.target_type is not None and not replace:
# Если целевой файл есть и нет параметра replace -- используем
# текст целевого файла.
if (not input_path.startswith(self.cl_config_archive_path) or
os.path.exists(input_path)):
# Если входной файл просто не из архива, или из архива и
# при этом существует -- используем его
with open(input_path, 'r') as input_file:
input_text = input_file.read()
if chmod:
self._chmod_file(template_object.target_path, chmod)
elif not template_object.format_class.EXECUTABLE:
# Действия при совпадении md5 из CONTENTS и md5 целевого файла.
# А также если шаблон просто исполнительный.
output_paths = [output_path]
# Если целевой файл защищен, а шаблон не userspace.
if (template_object.protected
and not template_object.is_userspace):
# Тогда также обновляем архив.
output_paths.append(template_object.archive_path)
if template_object.target_type is not None and not replace:
# Если целевой файл есть и нет параметра replace --
# используем текст целевого файла.
if (not input_path.startswith(self.cl_config_archive_path)
or os.path.exists(input_path)):
# Если входной файл просто не из архива, или из архива
# и при этом существует -- используем его
with open(input_path, 'r') as input_file:
input_text = input_file.read()
else:
# В противном случае используем пустой файл.
# TODO Подумать.
input_text = ''
else:
# В противном случае используем пустой файл. TODO Подумать.
input_text = ''
else:
input_text = ''
parsed_template = template_format(template_object.template_text,
template_object.template_path,
ignore_comments=True)
if not template_object.format_class.EXECUTABLE:
# Если шаблон не исполнительный разбираем входной текст.
parsed_input = template_format(
input_text,
@ -988,11 +1006,14 @@ class TemplateExecutor:
in self.processed_targets),
parameters=template_object.parameters)
parsed_input.join_template(parsed_template)
# Результат наложения шаблона.
output_text = parsed_input.document_text
# Удаляем форматный объект входного файла.
del(parsed_input)
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
input_text_md5 = hashlib.md5(input_text.encode()).hexdigest()
for save_path in output_paths:
if not os.path.exists(os.path.dirname(save_path)):
@ -1009,33 +1030,10 @@ class TemplateExecutor:
if chmod:
self._chmod_file(save_path, chmod)
if self.dbpkg:
# Убираем все ._cfg файлы.
if template_object.cfg_list:
for cfg_file_path in template_object.cfg_list:
self._remove_file(cfg_file_path)
# Убираем целевой файл из CL.
self.calculate_config_file.remove_file(
template_object.target_path)
if template_object.target_type is None:
self.changed_files[template_object.target_path] = 'N'
else:
self.changed_files[template_object.target_path] = 'M'
# Обновляем CONTENTS.
if template_object.protected:
if template_object.parameters.unbound:
template_object.remove_from_contents()
else:
template_object.add_to_contents(
file_md5=output_text_md5)
else:
elif template_object.format_class.EXECUTABLE:
changed_files = parsed_template.execute_format(
input_text=input_text,
target_path=template_object.target_path)
template_object.target_path,
chroot_path=self.chroot_path)
# Удаляем форматный объект входного файла.
del(parsed_template)
# Если исполняемый формат выдал список измененных файлов для
@ -1062,6 +1060,33 @@ class TemplateExecutor:
template_object.target_package and
template_object.format_class.FORMAT != 'contents'):
template_object.update_contents_from_list(changed_files)
return
if input_text_md5 != output_text_md5:
if template_object.target_type is None:
self.changed_files[
template_object.target_path] = 'N'
else:
self.changed_files[
template_object.target_path] = 'M'
if self.dbpkg:
# Убираем все ._cfg файлы.
if template_object.cfg_list:
for cfg_file_path in template_object.cfg_list:
self._remove_file(cfg_file_path)
# Убираем целевой файл из CL.
self.calculate_config_file.remove_file(
template_object.target_path)
# Обновляем CONTENTS.
if template_object.protected:
if template_object.parameters.unbound:
template_object.remove_from_contents()
else:
template_object.add_to_contents(
file_md5=output_text_md5)
else:
if template_object.target_type is not None and not replace:
if (not input_path.startswith(self.cl_config_archive_path) or

@ -13,6 +13,7 @@ markers =
kernel: marker for running test for kernel format.
ldap: marker for running test for ldap format.
openrc: marker for running test for openrc format.
raw: marker for running test fot raw format.
regex: marker for running test fot regex format.
postfix: marker for running test for postfix format.
procmail: marker for running test for procmail format.

@ -0,0 +1,137 @@
import pytest
from collections import OrderedDict
from calculate.templates.format.raw_format import RawFormat
@pytest.mark.raw
class TestParsingMethods:
def test_first(self):
original = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
template = '''parameter-4 = d;
parameter-5 = e;'''
output = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;
parameter-4 = d;
parameter-5 = e;'''
raw_document_1 = RawFormat(original, 'path/to/template')
raw_document_2 = RawFormat(template, 'path/to/template')
raw_document_1.join_template(raw_document_2)
assert raw_document_1.document_text == output
def test_second(self):
document_1 = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
document_2 = '''parameter-4 = d;
parameter-5 = e;'''
output = '''parameter-4 = d;
parameter-5 = e;
parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
raw_document_1 = RawFormat(document_1, 'path/to/template',
join_before=True)
raw_document_2 = RawFormat(document_2, 'path/to/template')
raw_document_1.join_template(raw_document_2)
assert raw_document_1.document_text == output
def test_first_with_comment(self):
document_1 = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
document_2 = '''parameter-4 = d;
parameter-5 = e;'''
output = '''#-------------------------------------------------------------------------------
# Modified by Calculate Utilities 4.0
# Processed template files:
# path/to/template
#-------------------------------------------------------------------------------
parameter-1 = a;
parameter-2 = b;
parameter-3 = c;
parameter-4 = d;
parameter-5 = e;'''
raw_document_1 = RawFormat(document_1, 'path/to/template',
add_header=True)
raw_document_2 = RawFormat(document_2, 'path/to/template')
raw_document_1.join_template(raw_document_2)
assert raw_document_1.document_text == output
def test_second_with_comment(self):
document_1 = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
document_2 = '''parameter-4 = d;
parameter-5 = e;'''
output = '''#-------------------------------------------------------------------------------
# Modified by Calculate Utilities 4.0
# Processed template files:
# path/to/template
#-------------------------------------------------------------------------------
parameter-4 = d;
parameter-5 = e;
parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
raw_document_1 = RawFormat(document_1, 'path/to/template',
join_before=True, add_header=True)
raw_document_2 = RawFormat(document_2, 'path/to/template')
raw_document_1.join_template(raw_document_2)
assert raw_document_1.document_text == output
def test_third_with_comment(self):
original_text = '''parameter-1 = a;
parameter-2 = b;
parameter-3 = c;'''
template_text_1 = '''parameter-4 = d;
parameter-5 = e;'''
template_text_2 = '''parameter-6 = f;'''
output = '''#-------------------------------------------------------------------------------
# Modified by Calculate Utilities 4.0
# Processed template files:
# path/to/template_1
# path/to/template_2
#-------------------------------------------------------------------------------
parameter-1 = a;
parameter-2 = b;
parameter-3 = c;
parameter-4 = d;
parameter-5 = e;
parameter-6 = f;'''
original_1 = RawFormat(original_text, 'path/to/template_1',
add_header=True,
already_changed=False)
template_1 = RawFormat(template_text_1, 'path/to/template_1')
template_2 = RawFormat(template_text_2, 'path/to/template_2')
original_1.join_template(template_1)
original_2 = RawFormat(original_1.document_text, 'path/to/template_2',
add_header=True,
already_changed=True)
original_2.join_template(template_2)
assert original_2.document_text == output

@ -1379,6 +1379,17 @@ class TestDirectoryProcessor:
assert '/etc/dir_59' in test_package_0
assert '/etc/dir_59/file_0' in test_package_0
def test_copy_file_using_source(self):
datavars.main['cl_template_path'] = os.path.join(CHROOT_PATH,
'templates_42')
directory_processor = DirectoryProcessor(
'install',
datavars_module=datavars,
package='test-category/test-package'
)
directory_processor.process_template_directories()
assert os.path.exists(join_paths(CHROOT_PATH, '/etc/copy.gif'))
def test_view_tree(self):
list_path = join_paths(CHROOT_PATH, '/etc')
show_tree(list_path)

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -0,0 +1 @@
{% calculate action = "install", append = "skip", path = "/etc" %}

@ -0,0 +1,2 @@
{% calculate append = "join", format = "raw", source = "/etc/img.gif",
name = "copy.gif", package = "test-category/test-package" -%}
Loading…
Cancel
Save