From a2dfb57e818fb3aa55523ff80411d4467a44cba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=81?= Date: Fri, 15 May 2020 14:31:02 +0300 Subject: [PATCH] Postparsing parameters processing is added to the template engine. --- calculate/templates/template_engine.py | 51 ++++++++++++++++---- calculate/templates/template_processor.py | 15 ++++-- template_action_draft.py | 34 ++++++++++--- tests/templates/test_parameters_processor.py | 16 +++++- 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/calculate/templates/template_engine.py b/calculate/templates/template_engine.py index 7bbfa5a..accb478 100644 --- a/calculate/templates/template_engine.py +++ b/calculate/templates/template_engine.py @@ -128,6 +128,13 @@ class ParametersProcessor: 'merge': self.check_merge_parameter }) + # Если добавляемый параметр должен быть проверен после того, как + # будет закончен парсинг всех других параметров -- добавляем сюда метод + # для проверки. + self.postparse_checkers_list = OrderedDict({ + 'append': self.check_postparse_append, + 'source': self.check_postparse_source}) + # Если параметр является наследуемым только при некоторых условиях -- # указываем здесь эти условия. self.inherit_conditions = {'chmod': self.is_chmod_inheritable} @@ -175,7 +182,16 @@ class ParametersProcessor: return self._parameters_container.set_parameter( - {parameter_name: checked_value}) + {parameter_name: checked_value}) + + def check_postparse_parameters(self): + for parameter, parameter_checker in\ + self.postparse_checkers_list.items(): + if not self._parameters_container[parameter]: + continue + + parameter_value = self._parameters_container[parameter] + parameter_checker(parameter_value) def check_template_parameters(self, parameters, template_type, lineno): self.template_type = template_type @@ -303,10 +319,12 @@ class ParametersProcessor: num = num + '1' else: num = num + '0' + parameter_value = parameter_value + num return int(parameter_value, 2) elif parameter_value.isdigit(): parameter_value = int(parameter_value, 8) + return parameter_value else: raise IncorrectParameter("'chmod' parameter value is not correct") @@ -319,16 +337,11 @@ class ParametersProcessor: if not parameter_value or isinstance(parameter_value, bool): raise IncorrectParameter("'source' parameter value is empty") - elif (self.template_type == DIR and - ('append' not in self._parameters_container or - self._parameters_container['append'] != 'link')): - raise IncorrectParameter( - ("'source' parameter is set without " - "'append = link' for directory template") - ) + elif not os.path.exists(real_path): raise IncorrectParameter( "File from 'source' parameter does not exist") + return os.path.normpath(real_path) def check_env_parameter(self, parameter_value): @@ -365,8 +378,24 @@ class ParametersProcessor: raise IncorrectParameter( "'autoupdate' parameter value is not bool") + def check_postparse_append(self, parameter_value): + if parameter_value == 'link': + if 'source' not in self._parameters_container: + raise IncorrectParameter("append = 'link' without source " + "parameter.") + + def check_postparse_source(self, parameter_value): + if (self.template_type == DIR and + ('append' not in self._parameters_container or + self._parameters_container['append'] != 'link')): + raise IncorrectParameter( + ("'source' parameter is set without " + "append = 'link' for directory template") + ) + def is_chmod_inheritable(self, parameter_value): chmod_regex = re.compile(r'\d+') + if chmod_regex.search(parameter_value): return False return True @@ -594,7 +623,7 @@ class ParametersContainer(MutableMapping): elif name in self.__inheritable: return self.__inheritable[name] else: - raise KeyError() + return False def __setitem__(self, name, value): self.__parameters[name] = value @@ -944,6 +973,8 @@ class TemplateEngine: self.calculate_extension.template_type = template_type template = self.environment.get_template(template_path) + self.parameters_processor.check_postparse_parameters() + self._template_text = template.render( __datavars__=self._datavars_module, __parameters__=self._parameters_object, @@ -970,6 +1001,8 @@ class TemplateEngine: self.calculate_extension.template_type = template_type template = self.environment.from_string(string) + self.parameters_processor.check_postparse_parameters() + self._template_text = template.render( __datavars__=self._datavars_module, __parameters__=self._parameters_object, diff --git a/calculate/templates/template_processor.py b/calculate/templates/template_processor.py index f8434be..429509d 100644 --- a/calculate/templates/template_processor.py +++ b/calculate/templates/template_processor.py @@ -24,7 +24,7 @@ class TemplateError(Exception): pass -class SystemAction: +class TemplateTypeConflict(Exception): pass @@ -761,10 +761,15 @@ class DirectoryProcessor: self.output.set_success('Processing directory: {}'. format(current_directory_path)) - self.template_action.process_template_directory( - current_target_path, - template_path=current_directory_path, - parameters=directory_parameters) + try: + self.template_action.process_template_directory( + current_target_path, + template_path=current_directory_path, + parameters=directory_parameters) + except TemplateTypeConflict as error: + self.output.set_error('Type conflict: {}\nTemplate: {}'. + format(str(error), + current_directory_path)) else: self.output.set_success('Processing directory: {}'. format(current_directory_path)) diff --git a/template_action_draft.py b/template_action_draft.py index 59b2172..07b1ae3 100644 --- a/template_action_draft.py +++ b/template_action_draft.py @@ -2,6 +2,7 @@ from calculate.templates.template_engine import TemplateEngine, Variables,\ FILE, DIR, LINK,\ ParametersProcessor from calculate.templates.template_processor import TemplateAction +from calculate.utils.package import PackageAtomParser import shutil import os @@ -45,6 +46,9 @@ class TemplateWrapper: type_checks = {DIR: os.path.isdir, FILE: os.path.isfile} + chroot_path = '/' + package_atom_parser = PackageAtomParser(chroot_path = chroot_path) + def __init__(self, target_file_path, parameters, template_type, template_text=''): self._target_path = target_file_path @@ -113,8 +117,25 @@ class TemplateWrapper: raise TemplateTypeConflict("The target file is a directory" " while the template is a file.") - def append_template(): - pass + def check_original_file(self): + if self.parameters.package: + package_atom = self.parameters.package + else: + # пока что определяем значение package для всех файлов. + package_atom = package_atom_parser.get_file_package() + + def join_template(self): + if self.template_type is not None: + original_file_text = '' + + original_file = open(self._target_path, 'w') + else: + original_file = open(self._target_path, 'r') + original_file_text = original_file.read() + original_file.close() + + original_file = open(self._target_path, 'w') + class TemplateExecutor: @@ -152,7 +173,8 @@ class TemplateExecutor: self.directory_appends[template_object.parameters.append]( template_object) - def _append_join_directory(self, target_path): + def _create_directory(self, template_object): + target_path = template_object.target_path print("append = 'join'") if os.access(target_path, os.F_OK): if self.template_parameters.chmod: @@ -206,7 +228,7 @@ class TemplateExecutor: 'Failed to create directory: {}, reason: {}'. format(create_path, str(error))) - def _append_remove_directory(self, target_path): + def _remove_directory(self, target_path): print("append = 'remove'") if os.path.isdir(target_path) or os.path.exists(target_path): try: @@ -229,7 +251,7 @@ class TemplateExecutor: format(target_path)) return False - def _append_clear_directory(self, target_path): + def _clear_directory(self, target_path): print("append = 'clear'") if os.path.isdir(target_path): if os.path.exists(target_path): @@ -253,7 +275,7 @@ class TemplateExecutor: "Failed to delete the directory: {}, reason: {}.". format(target_path, error_message)) - def _append_skip_directory(self, target_path): + def _skip_directory(self, target_path): print("append = 'skip'") return diff --git a/tests/templates/test_parameters_processor.py b/tests/templates/test_parameters_processor.py index 2c1c3a2..646eb49 100644 --- a/tests/templates/test_parameters_processor.py +++ b/tests/templates/test_parameters_processor.py @@ -28,6 +28,7 @@ class TestTemplateParameters: parameter_value, DIR, 1) + parameters_processor.check_postparse_parameters() assert (parameters_object.append == 'join' and parameters_object.chmod == 0o600 and parameters_object.force and @@ -43,6 +44,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_object.append == 'join' except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -59,6 +61,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_object.source == join_paths( CHROOT_PATH, '/test_dir_1/file.test') @@ -68,7 +71,6 @@ class TestTemplateParameters: finally: parameters_processor.chroot_path = '/' - def test_if_TemplateParameters_object_is_intialized_as_dir_parameters_object_using_correct_source_parameter_with_append_link__the_object_will_be_initialized_successfully(self): parameters = {'append': 'link', 'source': '/test_dir_1'} @@ -81,6 +83,7 @@ class TestTemplateParameters: parameter_value, DIR, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.source == join_paths(CHROOT_PATH, '/test_dir_1') except Exception as error: @@ -99,6 +102,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, DIR, 1) + parameters_processor.check_postparse_parameters() def test_if_TemplateParameters_object_is_intialized_as_dir_parameters_object_using_source_parameter_but_without_append_link__the_initialization_of_the_object_will_be_failed(self): parameters = {'source': '/test_dir_1/file.test'} @@ -111,6 +115,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, DIR, 1) + parameters_processor.check_postparse_parameters() def test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_force_parameter__the_object_will_be_initialized_successfully(self): parameters = {'force': True} @@ -123,6 +128,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, DIR, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.force except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -138,6 +144,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() def test_if_TemplateParameters_object_is_intialized_using_dictionary_with_autoupdate_parameter__a_value_of_the_parameter_will_be_checked(self): parameters = {'autoupdate': True} @@ -149,6 +156,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.autoupdate except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -164,6 +172,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() def test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chown_parameter__the_object_will_be_initialized_successfully(self): parameters = {'chown': 'root:root'} @@ -175,6 +184,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.chown == {'uid': 0, 'gid': 0} except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -192,6 +202,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.chown == {'uid': uid, 'gid': gid} except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -207,6 +218,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() def test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chmod_parameter__the_object_will_be_initialized_successfully(self): parameters = {'chmod': 'rw-r--r--'} @@ -218,6 +230,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.chmod == 0o644 except Exception as error: pytest.fail('Unexpected exception: {0}'. @@ -233,6 +246,7 @@ class TestTemplateParameters: parameters_processor.check_template_parameter(parameter_name, parameter_value, FILE, 1) + parameters_processor.check_postparse_parameters() assert parameters_processor.chmod == 0o600 except Exception as error: pytest.fail('Unexpected exception: {0}'.