chmod and chown parameters support is almost implemented.

packages
Иванов Денис 4 years ago
parent 6ead02a510
commit 0c662778d1

@ -1,185 +1,6 @@
{
"tests/templates/format/test_base.py::TestJoinMethod::test_if_input_dictionaries_have_no_sections_and_have_only_parameter_lines__it_will_be_processed_correctly": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_input_template_dictionary_has_delete_mark_for_parameter__parameter_will_be_deleted": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_input_template_dictionary_has_delete_mark_for_section__section_will_be_deleted": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_input_template_dictionary_has_replace_mark_for_section__section_will_be_deleted": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_inputs_are_dictionaries_with_parameters_with_same_name_in_same_section__parameters_values_in_original_dictionary_changed_to_values_from_template": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_inputs_are_dictionaries_with_same_sections_which_contain_different_parameters__a_section_from_the_template_added_to_the_same_section_of_original_dictionary": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_inputs_are_dictionaries_with_string_keys_without_any_action_marks__the_dictionaties_just_merged": true,
"tests/templates/format/test_base.py::TestJoinMethod::test_if_inputs_are_dictionaries_with_tuple_keys_without_any_action_marks_as_their_keys__the_dictionaries_just_merged": true,
"tests/templates/format/test_base.py::TestLogicLinesMethod::test_if_input_is_text_document_the_method_returns_list_of_its_lines": true,
"tests/templates/format/test_base.py::TestLogicLinesMethod::test_if_lines_in_document_divided_using_backslash_as_continuation_symbol__method_returns_list_of_full_lines": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_comment_parameter_is_set_for_template__format_object_will_parse_comments_with_comment_symbol_from_this_parameter": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_values_or_with_empty_block__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_input_document_contains_some_blocks_with_similar_names__the_blocks_join_recursively": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_bind.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_input_document_contains_sections_with_different_names_but_different_parameters__the_parameters_merged_in_one_section": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_if_the_ignore_comments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_compiz.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_contents.py::TestParsingMethods::test_if_input_document_contains_a_few_lines_with_some_action_symbols__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_contents.py::TestParsingMethods::test_if_input_document_contains_a_few_lines_without_any_action_symbols__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_contents.py::TestParsingMethods::test_if_template_parser_flag_is_set_False__the_initialized_object_contains_correct_dictionary_for_contents_util_module": true,
"tests/templates/format/test_contents.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_diff.py::TestExecuteMethods::test_if_diff_patch_used_for_patching_of_directories__it_changes_files_in_directories_and_adds_ones": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_values_or_with_empty_block__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_input_document_contains_some_blocks_with_similar_names__the_blocks_join_recursively": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_dovecot.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_json.py::TestParsingMethods::test_if_input_document_contains_just_few_parameters_and_parameter_blocks__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_json.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_json.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_parameters_with_values_with_unicode_symbols__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_sections_with_different_names_but_different_parameters__the_parameters_merged_in_one_section": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_kde.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_kernel.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_doc_contains_some_type_sections_with_plain_directives__object_dictionary_contains_correct_dictionary_with_directives_values_and_comments": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_doc_contains_some_type_sections_with_plain_directives_and_action_marks__object_dictionary_contains_correct_dictionary_with_directives_values_and_comments": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_document_contains_access_to_directive__the_object_s_dictionary_contains_correct_dictionary_with_list_of_access_to_parameters_and_comments": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_document_contains_comments_to_type_sections__the_object_s_dictionary_collect_them": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_document_contains_index_directives__the_object_s_dictionary_contains_correct_dictionary_with_index_elements_and_comments": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_document_contains_syncrepl_and_access_to_constructions_with_action_marks__object_dictionary_contains_correct_dictionary_with_action_marks": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_input_document_contains_syncrepl_directive__the_object_s_dictionary_contains_correct_dictionary_with_list_of_syncrepl_parameters_and_comments": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_logiclines_method_takes_text_with_lines_that_starts_whit_space_symbols__it_returns_joined_lines": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_if_template_text_contains_some_access_to_constuctions_with_same_what_value_and_without_action_marks_for_whole_constructions__they_join_in_one_access_to_construction": true,
"tests/templates/format/test_ldap.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_openrc.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_postfix.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_procmail.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_input_document_contains_blocks_and_parameters_with_action_marks__the_key_tuples_of_parameters_s_have_it_as_its_first_element_inherited": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_any_values_the_document_object_contains_dictionary_with_this_items_to_delete": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_input_document_contains_some_block_of_parameters__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_parameters_and_blocks_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value_or_with_special_key_in_block_dictionary": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_the_ignoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values_and_sections_to_delete__the_document_object_contains_dictionary_with_item_to_delete": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_sections_with_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_sections_with_similar_names_but_different_parameters__the_parameters_merged_in_one_section": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_parameters_contains_upper_case_symbols__it_becomes_lower_case": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_joinBefore_flag_is_set__the_document_object_contains_dictionary_with_sections_added_in_the_top_of_it": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_parameter_in_input_document_has_some_comments__the_comments_will_be_collected_in_the_list_of_parameter_value": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_the_IgnoreComments_flag_is_set__the_parser_ignores_all_comments": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_samba.py::TestParsingMethods::test_make_template": true,
"tests/templates/format/test_xml_gconf.py::TestParsingMethods::test_if_input_document_is_simple_gconf__the_format_object_contains_correct_dictionary": true,
"tests/templates/format/test_xml_gconf.py::TestParsingMethods::test_if_input_document_is_simple_gconf_tree__the_format_object_contains_correct_dictionary": true,
"tests/templates/format/test_xml_gconf.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/format/test_xml_xfce.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary": true,
"tests/templates/format/test_xml_xfce.py::TestParsingMethods::test_joining_documents_1": true,
"tests/templates/test_directory_processor.py::TestDirectoryProcessor::test_just_for_debug_with_package_value": true,
"tests/templates/test_directory_processor.py::TestDirectoryProcessor::test_just_for_debug_without_package_value": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_initialized_accoding_to_dictionary_of_correct_template_parameters__the_TemplateParameters_object_contains_processed_parameters_as_its_attributes_including_default_values": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_as_dir_parameters_object_using_correct_source_parameter_with_append_link__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::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": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_append_parameter__a_value_of_the_parameter_will_be_checked": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_autoupdate_parameter__a_value_of_the_parameter_will_be_checked": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chmod_parameter__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chmod_parameter_in_its_digital_form__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chown_parameter__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_chown_parameter_in_its_digital_form__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_force_parameter__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_correct_source_parameter__the_object_will_be_initialized_successfully": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_incorrect_autoupdate_parameter__the_initialization_of_the_object_will_be_failed": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_incorrect_chown_parameter__the_initialization_of_the_object_will_be_failed": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_dictionary_with_incorrect_force_parameter__the_initialization_of_the_object_will_be_failed": true,
"tests/templates/test_parameters_processor.py::TestTemplateParameters::test_if_TemplateParameters_object_is_intialized_using_source_parameter_with_unexisting_file_path__the_initialization_of_the_object_will_be_failed": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_chmod_directory": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_chown_directory": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_create_directory": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_link_directory": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_remove_directory": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_binded_with_datavars_module__variables_available_in_a_template": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_calculate_tag_contains_pkg_function_with_an_existing_package_in_its_argument__the_pkg_function_returns_version_value_of_the_package_from_package_parameter_without_any_exceptions": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_calculate_tag_with_some_parameters__the_template_engine_object_will_collect_its_parameters": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_condition_and_it_is_True__the_template_engine_object_will_be_initialized_without_any_exceptions": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_env_parameter_in_which_module_name_is_assigned__the_variables_from_this_module_can_be_used_in_template_without_determining_of_their_module": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_pkg_function_with_existing_package_as_its_argument__it_works_correctly_and_pkg_function_returns_version_value": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_pkg_function_with_package_that_does_not_exist_in_its_argument__it_works_correctly_and_pkg_function_returns_empty_version_value": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_pkg_function_without_any_arguments_and_without_package_parameter_in_calculate_tag__the_pkg_function_returns_empty_version_value": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_pkg_function_without_any_arguments_but_with_package_parameter_in_calculate_tag__the_pkg_function_returns_version_value_of_the_package_from_package_parameter": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_several_calculate_tags__the_template_engine_will_parse_them_all_and_will_contain_all_parameters_and_result_of_all_conditions": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_several_conditions_and_it_is_False__the_template_engine_raises_ConditionFailed_exception": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_an_input_template_contains_variables_in_its_text__the_rendered_text_will_contain_values_of_this_variables": true,
"tests/templates/test_template_engine.py::TestTemplateEngine::test_if_value_of_variable_is_set_using_save_tag__the_new_value_of_variable_can_be_used_in_template": true,
"tests/utils/test_files.py::TestUtils::test_if_a_pipe_Process_object_uses_for_several_writes__it_successfully_executes_even_after_read": true,
"tests/utils/test_files.py::TestUtils::test_if_a_pipe_Process_object_uses_for_several_writes_without_readings__it_successfully_executes": true,
"tests/utils/test_files.py::TestUtils::test_if_pipe_is_executed_using_Process_object__it_has_successfully_executed": true,
"tests/utils/test_files.py::TestUtils::test_if_single_correct_command_executed_using_Process_object__it_successfully_executes": true,
"tests/utils/test_package.py::TestContents::test_if_PackageContents_object_contains_contents_dictionary__it_renders_CONTENTS_file_correctly": true,
"tests/utils/test_package.py::TestContents::test_if_PackageContents_object_initialized_by_existing_package__it_contains_dictionary_of_items_from_contents_file": true,
"tests/utils/test_package.py::TestContents::test_if_new_directory_is_added_in_contents_file_using_add_dir_method__the_PackageContents_object_renders_the_contents_file_with_new_dir": true,
"tests/utils/test_package.py::TestContents::test_if_new_link_is_added_in_contents_file_using_add_sym_method__the_PackageContents_object_renders_the_contents_file_with_new_sym": true,
"tests/utils/test_package.py::TestContents::test_if_new_object_is_added_in_contents_file_using_add_obj_method__the_PackageContents_object_renders_the_contents_file_with_new_obj": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_but_without_a_slot_and_use_flags__the_PackageAtom_object_returns_atom_name_of_package": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_slot_value__the_PackageAtom_returns_atom_name_of_package_with_this_slot": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_a_uses_value__the_PackageAtom_object_returns_atom_name_of_package_with_this_use_flags": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parsed_a_correct_package_atom_name_with_an_empty_slot_value__the_PackageAtom_object_returns_atom_name_of_package": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parses_a_correct_package_atom_name_without_version_value_but_with_slot_value__the_PackageAtom_object_looks_for_package_with_assigned_slot_value": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_parses_a_correct_package_atom_name_without_version_value_but_with_use_flags_value__the_PackageAtom_object_looks_for_package_with_assigned_use_flags": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_tried_to_parse_an_correct_package_atom_name_that_matches_multiple_packages__the_PackageAtom_object_gets_info_for_package_with_older_version": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_tried_to_parse_an_incorrect_package_atom_name__the_PackageAtom_object_throws_the_PackageAtomError_exception": true,
"tests/utils/test_package.py::TestContents::test_if_the_PackageAtom_object_tried_to_parse_an_package_atom_name_with_incorrect_use_flags__the_PackageAtom_object_throws_the_PackageAtomError_exception": true,
"tests/utils/test_package.py::TestContents::test_if_the_get_file_package_method_of_the_PackageAtom_object_is_called_with_a_name_of_a_file_that_belongs_to_any_package__the_PackageAtom_object_contains_dictionary_with_an_owner_package": true,
"tests/utils/test_package.py::TestContents::test_if_the_get_file_package_method_of_the_PackageAtom_object_is_called_with_a_name_of_a_file_that_does_not_belong_to_any_package__the_PackageAtom_object_throws_the_PackageAtomError_exception": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_eq_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_ge_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_gt_operation_and_the_left_version_value_is_less_than_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_le_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_lt_operation_and_the_left_version_value_is_less_than_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/utils/test_package.py::TestContents::test_if_two_Version_objects_compared_using_ne_operation_and_the_left_version_value_is_less_than_or_equal_to_the_right_version__the_result_of_the_comparing_would_be_True": true,
"tests/vars/test_namespace.py::TestNamespace::test_init_default_path": true,
"tests/vars/test_namespace.py::TestNamespace::test_init_empty_namespace": true
"tests/templates/format/test_regex.py::TestParsingMethods::test_if_input_patch_document_contains_only_regular_expressions_without_any_regex_flags__it_correctly_patches_input_document": true,
"tests/templates/format/test_regex.py::TestParsingMethods::test_if_input_patch_document_contains_regular_expressions_with_global_regex_flags_and_flags_as_attributes__it_correctly_patches_input_document_using_regex_flags": true,
"tests/templates/test_template_action.py::TestTemplateAction::test_create_directory": true
}

@ -115,8 +115,6 @@
"tests/templates/format/test_openrc.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_assign_symbol_and_any_values__the_document_object_contains_dictionary_with_item_to_delete",
"tests/templates/format/test_openrc.py::TestParsingMethods::test_joining_documents_1",
"tests/templates/format/test_openrc.py::TestParsingMethods::test_make_template",
"tests/templates/format/test_patch.py::TestParsingMethods::test_if_input_patch_document_contains_only_regular_expressions_without_any_regex_flags__it_correctly_patches_input_document",
"tests/templates/format/test_patch.py::TestParsingMethods::test_if_input_patch_document_contains_regular_expressions_with_global_regex_flags_and_flags_as_attributes__it_correctly_patches_input_document_using_regex_flags",
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary",
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary",
"tests/templates/format/test_postfix.py::TestParsingMethods::test_if_input_document_contains_parameters_with_action_marks__the_key_tuples_of_object_s_dictionary_have_it_as_its_first_element",
@ -140,6 +138,8 @@
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_the_ignoreComments_flag_is_set__the_parser_ignores_all_comments",
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_if_input_document_contains_parameters_to_delete_without_any_values_the_document_object_contains_dictionary_with_this_items_to_delete",
"tests/templates/format/test_proftpd.py::TestParsingMethods::test_joining_documents_1",
"tests/templates/format/test_regex.py::TestParsingMethods::test_if_input_patch_document_contains_only_regular_expressions_without_any_regex_flags__it_correctly_patches_input_document",
"tests/templates/format/test_regex.py::TestParsingMethods::test_if_input_patch_document_contains_regular_expressions_with_global_regex_flags_and_flags_as_attributes__it_correctly_patches_input_document_using_regex_flags",
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_just_few_parameter_lines__the_initialised_object_contains_correct_dictionary",
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_few_parameter_lines_and_some_empty_lines__the_initialized_object_contains_correct_dictionary",
"tests/templates/format/test_samba.py::TestParsingMethods::test_if_input_document_contains_sections_with_similar_names_but_different_parameters__the_parameters_merged_in_one_section",

@ -1,84 +0,0 @@
# vim: fileencoding=utf-8
#
from .base_format import BaseFormat
from ..template_engine import ParametersContainer
from calculate.utils.files import Process
from calculate.templates.format.base_format import FormatError
from os import path
class DiffFormat(BaseFormat):
FORMAT = 'diff'
EXECUTABLE = True
def __init__(self, document_text: str,
join_before=False,
parameters=ParametersContainer()):
self._patch_text = document_text
self._cwd_path = '/'
self._last_level = 0
# Измененные файлы.
self.changed_files = dict()
def execute_format(self, target_path):
'''Метод для запуска работы формата.'''
self._cwd_path = target_path
if not path.isdir(self._cwd_path):
# Если target_path -- путь к файлу, запускаем все процессы из
# директории, в которой этот файл находится.
self._cwd_path = path.dirname(self._cwd_path)
if not path.exists(self._cwd_path):
raise FormatError('root path does not exist')
if self._patch_text:
self._patch_document()
return self.changed_files
else:
raise FormatError('empty patch file')
def _patch_document(self):
'''Метод, производящий наложение патча путем запуска процесса patch.'''
# Сначала определяем на каком уровне накладываем патч.
# Для этого запускаем утилиту patch с --dry-run и смотрим результат
# выполнения.
for level in range(0, 4):
patch_dry_run = Process('patch', '--dry-run',
'-p{}'.format(level),
cwd=self._cwd_path)
patch_dry_run.write(self._patch_text)
if patch_dry_run.success():
break
patch_dry_run = Process('patch', '-R', '--dry-run',
'-p{}'.format(level),
cwd=self._cwd_path)
patch_dry_run.write(self._patch_text)
if patch_dry_run.success():
return ''
else:
raise FormatError('correction failed')
self._last_level = level
patch_run = Process('patch', '-p{}'.format(level),
cwd=self._cwd_path)
patch_run.write(self._patch_text)
if patch_run.success():
for line in patch_run.read_lines():
if line.startswith('patching file'):
changed_file_path = path.join(self._cwd_path,
line[13:].strip())
if path.exists(changed_file_path):
self.changed_files.update({changed_file_path:
'modify'})
else:
self.changed_files.update({changed_file_path:
'remove'})
print('Changings: ')
for file_path, change_type in self.changed_files.items():
print('{}: {}'.format(file_path, change_type))
return patch_run.read()
else:
return ''

@ -1,183 +1,84 @@
# vim: fileencoding=utf-8
#
from .base_format import BaseFormat, FormatError
from .base_format import BaseFormat
from ..template_engine import ParametersContainer
from collections import OrderedDict
import re
try:
from lxml.etree.ElementTree import fromstring
except ImportError:
from xml.etree.ElementTree import fromstring
from calculate.utils.files import Process
from calculate.templates.format.base_format import FormatError
from os import path
class PatchFormat(BaseFormat):
FORMAT = 'patch'
EXECUTABLE = False
FORMAT_PARAMETERS = {'multiline', 'dotall', 'comment'}
EXECUTABLE = True
def __init__(self, document_text: str,
ignore_comments=False,
join_before=False,
parameters=ParametersContainer()):
processing_methods = OrderedDict()
super().__init__(processing_methods)
self._patch_text = document_text
self._cwd_path = '/'
self._last_level = 0
# Измененные файлы.
self.changed_files = dict()
self._multiline_flag = parameters.multiline
self._dotall_flag = parameters.dotall
self._parsed_patch = None
def execute_format(self, target_path):
'''Метод для запуска работы формата.'''
self._cwd_path = target_path
if not path.isdir(self._cwd_path):
# Если target_path -- путь к файлу, запускаем все процессы из
# директории, в которой этот файл находится.
self._cwd_path = path.dirname(self._cwd_path)
self._document_text = document_text
self._FLAG_VALUES = {'True': True,
'False': False,
'true': True,
'false': False,
'1': True,
'0': False}
if not path.exists(self._cwd_path):
raise FormatError('root path does not exist')
self._XML_ROOT_LINE = '<?xml version="1.0" encoding="utf-8"?>\
<patch>{0}</patch>'
def _parse_patch(self, patch_text):
'''Метод, составляющий из текста шаблона xml документ и разбирающий его
с помощью lxml.'''
xml_patch = self._XML_ROOT_LINE.format(patch_text.strip())
try:
self._parsed_patch = fromstring(xml_patch)
except Exception:
raise FormatError('can not parse patch document')
def join_template(self, template):
tmp_multiline = template._multiline_flag
tmp_dotall = template._dotall_flag
template._multiline_flag = self._multiline_flag
template._dotall_flag = self._dotall_flag
self._document_text = template._join(self._document_text)
template._multiline_flag = tmp_multiline
template._dotall_flag = tmp_dotall
def _join(self, input_text):
'''Метод для запуска наложения патча.'''
self._parse_patch(self._document_text)
if not input_text.strip() == '':
self._document_to_patch = input_text
if self._patch_text:
self._patch_document()
return self.changed_files
else:
return input_text
if not self._patch_document(input_text):
raise FormatError('Error: Can not run patch.')
raise FormatError('empty patch file')
def _patch_document(self):
'''Метод, производящий наложение патча путем запуска процесса patch.'''
# Сначала определяем на каком уровне накладываем патч.
# Для этого запускаем утилиту patch с --dry-run и смотрим результат
# выполнения.
for level in range(0, 4):
patch_dry_run = Process('patch', '--dry-run',
'-p{}'.format(level),
cwd=self._cwd_path)
patch_dry_run.write(self._patch_text)
if patch_dry_run.success():
break
patch_dry_run = Process('patch', '-R', '--dry-run',
'-p{}'.format(level),
cwd=self._cwd_path)
patch_dry_run.write(self._patch_text)
if patch_dry_run.success():
return ''
else:
after_patch = self._document_to_patch
self._document_to_patch = ''
return after_patch
def _patch_document(self, document_to_patch):
'''Метод, обходящий теги шаблона и использующий указанные в нем
регулярные выражения.'''
patch_iterator = self._parsed_patch.getiterator()
PATCH_DOCUMENT_TAGS = ('reg', 'text')
patch_element = next(patch_iterator, False)
if not patch_element or not patch_element.tag == 'patch':
raise FormatError('incorrect text of the template')
while True:
for patch_tag in PATCH_DOCUMENT_TAGS:
patch_element = next(patch_iterator, None)
if patch_element is None:
if patch_tag == 'text':
raise FormatError('last <text>Text</text> '
'object is missed.')
raise FormatError('correction failed')
self._last_level = level
patch_run = Process('patch', '-p{}'.format(level),
cwd=self._cwd_path)
patch_run.write(self._patch_text)
if patch_run.success():
for line in patch_run.read_lines():
if line.startswith('patching file'):
changed_file_path = path.join(self._cwd_path,
line[13:].strip())
if path.exists(changed_file_path):
self.changed_files.update({changed_file_path:
'modify'})
else:
break
if patch_element.tag == patch_tag:
if patch_element.text is not None:
element_text = patch_element.text.strip()
if element_text == '':
raise FormatError(
("Error: Incorrect text of the "
"template: <{0}>%s</{0}>").format(
patch_tag
))
else:
raise FormatError("Error: Incorrect text of the "
"template: <{0}></{0}>").format(
patch_tag
)
if patch_tag == 'reg':
dotall = patch_element.attrib.get('dotall', False)
regex_flags = 0
if 'multiline' in patch_element.attrib:
multiline = patch_element.attrib['multiline']
if multiline not in self._FLAG_VALUES:
raise FormatError('invalid multiline value')
else:
multiline = self._FLAG_VALUES[multiline]
# Если глобально флаг MULTILINE включен, но в
# атрибутах тэга <reg> этот флаг присутствует со
# значением False -- для этого регулярного
# выражения этот флаг также будет False.
multiline_global = self._multiline_flag & multiline
else:
multiline = False
multiline_global = self._multiline_flag
if multiline_global or multiline:
regex_flags |= re.MULTILINE
if 'dotall' in patch_element.attrib:
dotall = patch_element.attrib['dotall']
if dotall not in self._FLAG_VALUES:
raise FormatError('invalid dotall value')
else:
dotall = self._FLAG_VALUES[dotall]
# Если глобально флаг DOTALL включен, но в
# атрибутах тэга <reg> этот флаг присутствует со
# значением False -- для этого регулярного
# выражения этот флаг также будет False.
dotall_global = self._dotall_flag & dotall
else:
dotall = False
dotall_global = self._dotall_flag
if dotall_global or dotall:
regex_flags |= re.DOTALL
regex_expression = re.compile(element_text,
regex_flags)
else:
text_for_replace = element_text
else:
if patch_element.tag in PATCH_DOCUMENT_TAGS:
error_message = '<{0}> is expected, <{1}> instead.'.\
format(patch_tag,
patch_element.tag)
else:
error_message = 'unknown tag: {0}'.format(
patch_element.tag
)
raise ("incorrect text of the template: {}".format(
error_message))
else:
self._document_to_patch = re.sub(regex_expression,
text_for_replace,
self._document_to_patch)
continue
return True
@property
def document_text(self):
return self._document_text
self.changed_files.update({changed_file_path:
'remove'})
print('Changings: ')
for file_path, change_type in self.changed_files.items():
print('{}: {}'.format(file_path, change_type))
return patch_run.read()
else:
return ''

@ -0,0 +1,183 @@
# vim: fileencoding=utf-8
#
from .base_format import BaseFormat, FormatError
from ..template_engine import ParametersContainer
from collections import OrderedDict
import re
try:
from lxml.etree.ElementTree import fromstring
except ImportError:
from xml.etree.ElementTree import fromstring
class RegexFormat(BaseFormat):
FORMAT = 'regex'
EXECUTABLE = False
FORMAT_PARAMETERS = {'multiline', 'dotall', 'comment'}
def __init__(self, document_text: str,
ignore_comments=False,
join_before=False,
parameters=ParametersContainer()):
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
self._document_text = document_text
self._FLAG_VALUES = {'True': True,
'False': False,
'true': True,
'false': False,
'1': True,
'0': False}
self._XML_ROOT_LINE = '<?xml version="1.0" encoding="utf-8"?>\
<patch>{0}</patch>'
def _parse_patch(self, patch_text):
'''Метод, составляющий из текста шаблона xml документ и разбирающий его
с помощью lxml.'''
xml_patch = self._XML_ROOT_LINE.format(patch_text.strip())
try:
self._parsed_patch = fromstring(xml_patch)
except Exception:
raise FormatError('can not parse patch document')
def join_template(self, template):
tmp_multiline = template._multiline_flag
tmp_dotall = template._dotall_flag
template._multiline_flag = self._multiline_flag
template._dotall_flag = self._dotall_flag
self._document_text = template._join(self._document_text)
template._multiline_flag = tmp_multiline
template._dotall_flag = tmp_dotall
def _join(self, input_text):
'''Метод для запуска наложения патча.'''
self._parse_patch(self._document_text)
if not input_text.strip() == '':
self._document_to_patch = input_text
else:
return input_text
if not self._patch_document(input_text):
raise FormatError('Error: Can not run patch.')
else:
after_patch = self._document_to_patch
self._document_to_patch = ''
return after_patch
def _patch_document(self, document_to_patch):
'''Метод, обходящий теги шаблона и использующий указанные в нем
регулярные выражения.'''
patch_iterator = self._parsed_patch.getiterator()
PATCH_DOCUMENT_TAGS = ('reg', 'text')
patch_element = next(patch_iterator, False)
if not patch_element or not patch_element.tag == 'patch':
raise FormatError('incorrect text of the template')
while True:
for patch_tag in PATCH_DOCUMENT_TAGS:
patch_element = next(patch_iterator, None)
if patch_element is None:
if patch_tag == 'text':
raise FormatError('last <text>Text</text> '
'object is missed.')
else:
break
if patch_element.tag == patch_tag:
if patch_element.text is not None:
element_text = patch_element.text.strip()
if element_text == '':
raise FormatError(
("Error: Incorrect text of the "
"template: <{0}>%s</{0}>").format(
patch_tag
))
else:
raise FormatError("Error: Incorrect text of the "
"template: <{0}></{0}>").format(
patch_tag
)
if patch_tag == 'reg':
dotall = patch_element.attrib.get('dotall', False)
regex_flags = 0
if 'multiline' in patch_element.attrib:
multiline = patch_element.attrib['multiline']
if multiline not in self._FLAG_VALUES:
raise FormatError('invalid multiline value')
else:
multiline = self._FLAG_VALUES[multiline]
# Если глобально флаг MULTILINE включен, но в
# атрибутах тэга <reg> этот флаг присутствует со
# значением False -- для этого регулярного
# выражения этот флаг также будет False.
multiline_global = self._multiline_flag & multiline
else:
multiline = False
multiline_global = self._multiline_flag
if multiline_global or multiline:
regex_flags |= re.MULTILINE
if 'dotall' in patch_element.attrib:
dotall = patch_element.attrib['dotall']
if dotall not in self._FLAG_VALUES:
raise FormatError('invalid dotall value')
else:
dotall = self._FLAG_VALUES[dotall]
# Если глобально флаг DOTALL включен, но в
# атрибутах тэга <reg> этот флаг присутствует со
# значением False -- для этого регулярного
# выражения этот флаг также будет False.
dotall_global = self._dotall_flag & dotall
else:
dotall = False
dotall_global = self._dotall_flag
if dotall_global or dotall:
regex_flags |= re.DOTALL
regex_expression = re.compile(element_text,
regex_flags)
else:
text_for_replace = element_text
else:
if patch_element.tag in PATCH_DOCUMENT_TAGS:
error_message = '<{0}> is expected, <{1}> instead.'.\
format(patch_tag,
patch_element.tag)
else:
error_message = 'unknown tag: {0}'.format(
patch_element.tag
)
raise ("incorrect text of the template: {}".format(
error_message))
else:
self._document_to_patch = re.sub(regex_expression,
text_for_replace,
self._document_to_patch)
continue
return True
@property
def document_text(self):
return self._document_text

@ -508,15 +508,19 @@ class ParametersProcessor:
"""Взять uid из chroot passwd файла."""
passwd_file_path = os.path.join(self.chroot_path, 'etc/passwd')
passwd_dictionary = []
if os.path.exists(passwd_file_path):
with open(passwd_file_path, 'r') as passwd_file:
for line in passwd_file:
if line.startswith('#'):
continue
passwd_item = tuple(line.split(':')[0:3:2])
if (len(passwd_item) > 1 and passwd_item[0]
and passwd_item[0]):
passwd_dictionary.append(passwd_item)
passwd_dictionary = dict(passwd_dictionary)
return int(passwd_dictionary[user_name])
else:
@ -527,15 +531,20 @@ class ParametersProcessor:
"""Взять gid из chroot group файла."""
group_file_path = os.path.join(self.chroot_path, 'etc/group')
group_dictionary = []
if os.path.exists(group_file_path):
with open(group_file_path, 'r') as group_file:
for line in group_file:
if line.startswith('#'):
continue
group_item = tuple(line.split(':')[0:3:2])
if len(group_item) > 1 and group_item[0] and group_item[1]:
group_dictionary.append(group_item)
group_dictionary = dict(group_dictionary)
if group_name in group_dictionary:
return int(group_dictionary[group_name])
else:

@ -6,14 +6,14 @@ markers =
bind: marker for running tests for bind format.
compiz: marker for running tests for compiz format.
contents: marker for running tests for contents format.
diff: marker for running test for diff format.
patch: marker for running test for patch format.
dovecot: marker for running tests for devecot format.
json: marker for running tests for json format.
kde: marker for running test for kde format.
kernel: marker for running test for kernel format.
ldap: marker for running test for ldap format.
openrc: marker for running test for openrc format.
patch: marker for running test fot patch 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.
proftpd: marker for running tests for proftpd format.

@ -471,14 +471,30 @@ class TemplateWrapper:
if self.template_type == DIR:
self.target_package.clear_dir(self.target_path)
def add_to_contents(self, file_md5=None):
def add_to_contents(self, file_md5=None, file_path=None):
'''Метод для добавления целевого файла в CONTENTS.'''
if self.parameters.append == 'link':
self.target_package.add_sym(target_path, self.parameters.source)
self.target_package.add_sym(self.target_path,
self.parameters.source)
elif self.template_type == DIR:
self.target_package.add_dir(target_path)
self.target_package.add_dir(self.target_path)
elif self.template_type == FILE:
self.target_package.add_obj(target_path, file_md5)
self.target_package.add_obj(self.target_path, file_md5)
def update_contents_from_list(self, changed_list: dict):
for file_path, mode in changed_list.items():
if mode == "modify":
if os.path.islink(file_path):
self.target_package.add_sym(file_path)
elif os.path.isdir(file_path):
self.target_package.add_dir(file_path)
elif os.path.isfile(file_path):
self.target_package.add_obj(file_path)
elif mode == "remove":
if os.path.islink(file_path) or os.path.isfile(file_path):
self.target_package.remove_obj(file_path)
elif os.path.isdir(file_path):
self.target_package.add_dir(file_path)
@classmethod
def _set_protected(cls):
@ -658,14 +674,32 @@ class TemplateExecutor:
if template_object.target_type is not None:
self._clear_directory(template_object.target_path)
# Меняем права и владельца очищенной директории, если это
# необходимо.
if template_object.parameters.chmod:
self._chmod_directory(target_path,
template_object.parameters.chmod)
if template_object.parameters.chown:
self._chown_directory(target_path,
template_object.parameters.chown)
template_object.clear_dir_contents()
def _append_link_directory(self, template_object: TemplateWrapper):
'''Метод описывающий действия для append = "link", если шаблон --
директория. Создает ссылку на директорию, если она есть.'''
target = template_object.parameters.source
link_path = template_object.target_path
self._link_directory(link_path, target)
self._link_directory(template_object.parameters.source,
template_object.target_path)
# Меняем права и владельца файла, на который указывает ссылка.
if template_object.parameters.chmod:
self._chmod_directory(template_object.parameters.source,
template_object.parameters.chmod)
if template_object.parameters.chown:
self._chmod_directory(template_object.parameters.source,
template_object.parameters.chown)
template_object.add_to_contents()
@ -687,8 +721,33 @@ class TemplateExecutor:
output_path = template_object.output_path
template_format = template_object.format_class
print('target_path: ', template_object.target_path)
print('output_path: ', output_path)
if template_object.md5_matching:
# Задаемся значениями chmod и chown в зависимости от наличия или
# отсутствия файла.
try:
chmod = template_parameters.chmod
if not chmod:
chmod = self._get_file_mode(template_object.target_path)
elif template_object.target_type is not None:
chmod = self.directory_default_parameters.get('chmod',
False)
chown = template_parameters.chown
if not chown:
chown = self._get_file_owner(template_object.target_path)
elif template_object.target_type is not None:
chown = self.directory_default_parameters.get('chown',
False)
except OSError:
raise TemplateExecutorError('No access to the directory: {}'.
format(template_object.target_path))
print('chmod: ', chmod)
print('chown: ', chown)
if template_object.format_class.EXECUTABLE or\
template_object.md5_matching:
# Действия при совпадении md5 из CONTENTS и md5 целевого файла.
output_paths = [output_path]
@ -719,14 +778,14 @@ class TemplateExecutor:
with open(save_path, 'w') as output_file:
output_file.write(output_text)
if template_object.parameters.chown:
self.chown_file(save_path,
template_object.parameters.chown,
# Меняем права доступа и владельца всех сохраняемых файлов,
# если это необходимо.
if chown:
self.chown_file(save_path, chown,
check_existation=False)
if template_object.parameters.chmod:
self.chmod_file(save_path,
template_object.parameters.chmod,
if chmod:
self.chmod_file(save_path, chmod,
check_existation=False)
# Убираем все ._cfg файлы.
@ -746,24 +805,30 @@ class TemplateExecutor:
template_object.add_to_contents(
file_md5=output_text_md5)
else:
parsed_template.execute_format(
changed_files = parsed_template.execute_format(
input_text=input_text,
target_path=template_object.target_path)
# Удаляем форматный объект входного файла.
del(parsed_template)
# Если исполняемый формат выдал список измененных файлов для
# изменения CONTENTS -- обновляем CONTENTS.
if changed_files:
template_object.update_contents_from_list(changed_files)
else:
if template_object.target_type is not None and not replace:
with open(input_path, 'r') as input_file:
input_text = input_file.read()
parsed_input = template_format(input_text)
else:
input_text = ''
parsed_input = template_format(input_text)
parsed_template = template_format(template_object.template_text)
parsed_input.join_template(parsed_template)
# Результат наложения шаблона.
output_text = parsed_input.document_text
# Удаляем форматный объект входного файла.
del(parsed_input)
output_text_md5 = hashlib.md5(output_text.encode()).hexdigest()
@ -773,16 +838,18 @@ class TemplateExecutor:
with open(output_path, 'w') as output_file:
output_file.write(output_text)
if template_object.parameters.chown:
self.chown_file(output_path,
template_object.parameters.chown,
# Меняем права доступа и владельца ._cfg????_ файлов, если
# это необходимо.
if chown:
self.chown_file(output_path, chown,
check_existation=False)
if template_object.parameters.chmod:
if chmod:
self.chmod_file(output_file,
template_object.parameters.chmod,
check_existation=False)
# Обновляем CL.
self.calculate_config_file.set_files_md5(
template_object.target_path,
output_text_md5)
@ -794,90 +861,125 @@ class TemplateExecutor:
template_object.add_to_contents(file_md5=output_text_md5)
def _append_after_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "after", если шаблон --
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
в конец файла и в конец каждой секции файла.'''
self._append_join_file(template_object, join_before=False)
def _append_before_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "after", если шаблон --
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
в начало файла и в начало каждой секции файла.'''
self._append_join_file(template_object, join_before=True)
def _append_skip_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "skip". Пока никаких
действий.'''
pass
def _append_replace_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "replace", если шаблон --
файл. Очищает файл и затем накладывает на него шаблон.'''
self._append_join_file(template_object, replace=True)
def _append_remove_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "remove", если шаблон --
файл. Удаляет файл.'''
if template_object.target_type is not None:
self._remove_file(template_object.target_path)
template_object.remove_from_contents()
def _append_clear_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "clear", если шаблон --
файл. Очищает файл.'''
if template_object.target_type is not None:
self._clear_file(template_object.target_path)
else:
open(template_object.target_path, 'w').close()
template_object.add_to_contents()
# Меняем владельца и права доступа к очищенному файлу, если нужно.
if template_object.chown:
self.chown_file(template_object.target_path,
template_object.parameters.chown)
def _append_link_file(self, template_object: TemplateWrapper):
if template_object.target_type is not None:
self._link_file(template_object.target_path,
template_object.parameters.source)
if template_object.chmod:
self.chmod_file(template_object.target_path,
template_object.parameters.chown)
template_object.add_to_contents()
def _append_link_file(self, template_object: TemplateWrapper):
'''Метод описывающий действия при append = "link", если шаблон --
файл. Создает ссылку на файл, указанный в параметре source.'''
self._link_file(template_object.parameters.source,
template_object.parameters.target_path)
# Меняем права и владельца файла, на который указывает ссылка.
if template_object.parameters.chmod:
self.chmod_file(template_object.parameters.source,
template_object.parameters.chmod)
if template_object.parameters.chown:
self.chmod_file(template_object.parameters.source,
template_object.parameters.chown)
template_object.add_to_contents()
def _create_directory(self, template_object: TemplateWrapper):
'''Метод для создания директории и, при необходимости, изменения
владельца и доступа все директорий на пути к целевой.'''
target_path = template_object.target_path
template_parameters = template_object.parameters
# Если файл есть, но указан chmod или chown -- используем их.
if os.access(target_path, os.F_OK):
if template_parameters.chmod:
self.chmod_directory(target_path)
self._chmod_directory(target_path, template_parameters.chmod)
if self.template_parameters.chown:
self.chown_directory(target_path)
if template_parameters.chown:
self._chown_directory(target_path, template_parameters.chown)
return
directories_to_create = [target_path]
directory_path = os.path.dirname(target_path)
# Составляем список путей к директориям, которые нужно создать.
while not os.access(directory_path, os.F_OK) and directory_path:
directories_to_create.append(directory_path)
directory_path = os.path.dirname(directory_path)
# получаем информацию о владельце и правах доступа ближайшей
# существующей директории.
try:
current_mod, current_uid, current_gid = self.get_file_info(
directory_path,
'all')
current_owner = {'uid': current_uid, 'gid': current_gid}
chmod = template_parameters.chmod
if not chmod:
chmod = self._get_file_mode(directory_path)
else:
chmod = self.directory_default_parameters.get('chmod', False)
chown = template_parameters.chown
if not chown:
chown = self._get_file_owner(directory_path)
else:
chown = self.directory_default_parameters.get('chown', False)
except OSError:
raise TemplateExecutorError('No access to the directory: {}'.
format(directory_path))
raise TemplateExecutorError('No access to the directory: {}'.
format(directory_path))
directories_to_create.reverse()
# создаем директории.
for create_path in directories_to_create:
try:
os.mkdir(create_path)
if (template_parameters.chmod and
template_parameters.chmod != current_mod):
self.chmod_directory(create_path)
elif 'chmod' in self.directory_default_parameters:
self.chmod_directory(
create_path,
chmod_value=self.directory_default_parameters['chown'])
if (template_parameters.chown and
template_parameters.chown != current_owner):
self.chown_directory(create_path)
elif 'chown' in self.directory_default_parameters:
self.chown_directory(
create_path,
chown_value=self.directory_default_parameters['chmod'])
# Для каждой созданной директории меняем права и владельца
# если это необходимо.
if chmod:
self._chmod_directory(create_path, chmod)
if chown:
self._chown_directory(create_path, chown)
except OSError as error:
raise TemplateExecutorError(
@ -911,11 +1013,13 @@ class TemplateExecutor:
'''Метод для очистки содержимого целевой директории.'''
if os.path.exists(target_path):
if os.path.isdir(target_path):
# Удаляем все содержимое директории.
for node in os.scandir(target_path):
if node.is_dir():
self._remove_directory(node.path)
else:
self._remove_file(node.path)
return
else:
error_message = "target file is not directory"
else:
@ -925,7 +1029,7 @@ class TemplateExecutor:
" reason: {}").format(target_path,
error_message))
def _link_directory(self, target_path, source):
def _link_directory(self, source, target_path):
'''Метод для создания по целевому пути ссылки на директорию
расположенную на пути, указанному в source.'''
try:
@ -958,7 +1062,7 @@ class TemplateExecutor:
raise TemplateExecutorError("failed to clear the file: {}".
format(target_path))
def _link_file(self, target_path, source):
def _link_file(self, source, target_path):
'''Метод для создания по целевому пути ссылки на файл расположенный на
пути, указанному в source.'''
try:
@ -968,52 +1072,6 @@ class TemplateExecutor:
"Failed to create symlink to the file: {0} -> {1}".
format(target_path, self.source))
def chown_directory(self, target_path, chown_value={}):
"""Метод для смены владельца директории."""
if not chown_value:
chown_value = self.template_parameters.chown
print('chown value = {}'.format(chown_value))
try:
os.chown(target_path, chown_value['uid'], chown_value['gid'])
except (OSError, Exception) as error:
# возможно потребуются дополнительные проверки.
raise TemplateExecutorError(
'Can not chown directory: {0}, reason: {1}'.
format(target_path, str(error)))
def chmod_directory(self, target_path, chmod_value=False):
'''Метод для смены прав доступа к директории.'''
if not chmod_value:
chmod_value = self.template_parameters.chmod
try:
os.chmod(target_path, chmod_value)
except (OSError, Exception) as error:
# возможно потребуются дополнительные проверки.
self.output.set_error('Can not chmod directory: {0}, reason: {1}'.
format(target_path, str(error)))
def chown_file(self, target_path, chown_value, check_existation=True):
'''Метод для смены владельца файла.'''
try:
if check_existation and not os.path.exists(target_path):
open(target_path, 'w').close()
os.lchown(target_path, chown_value['uid'], chown_value['gid'])
except (OSError, Exception) as error:
# возможно потребуются дополнительные проверки.
raise TemplateExecutorError('Can not chown file: {0}, reason: {1}'.
format(target_path, str(error)))
def chmod_file(self, target_path, chmod_value, check_existation=True):
'''Метод для смены прав доступа к директории.'''
try:
if check_existation and not os.path.exists(target_path):
open(target_path, 'w').close()
os.chmod(target_path, chmod_value)
except (OSError, Exception) as error:
# возможно потребуются дополнительные проверки.
raise TemplateExecutorError('Can not chmod file: {0}, reason: {1}'.
format(target_path, str(error)))
def _run_template(self, template_object: TemplateWrapper):
'''Метод для сохранения текста шаблонов, который должен быть исполнен
интерпретатором указанным в run прямо во время обработки шаблонов.'''
@ -1045,18 +1103,24 @@ class TemplateExecutor:
'''
text_to_run = template_object.template_text
interpreter = template_object.parameters.exec
# Получаем путь к директории для хранения файлов .execute.
if (self.chroot_path != '/' and not
self.exec_files_directory.startswith(self.chroot_path)):
exec_files_directory = join_paths(self.chroot_path,
'/var/lib/calculate/.execute/')
# Если директория уже существует получаем номер очередного файла для
# exec по номеру последнего.
exec_number = 0
if os.path.exists(exec_files_directory):
exec_files_list = os.listdir(exec_files_directory)
if exec_files_list:
exec_number = int(exec_files_list[-1][-4:])
exec_number = str(exec_number + 1)
# Получаем название нового exec_???? файла.
if len(exec_number) < 4:
exec_number = '0' * (4 - len(exec_number)) + exec_number
exec_file_name = 'exec_{}'.format(exec_number)
@ -1067,63 +1131,119 @@ class TemplateExecutor:
exec_file.write(text_to_run)
exec_file.close()
# Добавляем новый файл в словарь файлов для дальнейшего исполнения.
self.executor_output['exec_file'] = {interpreter: exec_file_name}
def get_file_info(self, path, info='all'):
file_stat = os.stat(path)
if info == 'all':
return stat.S_IMODE(file_stat.st_mode), file_stat.st_uid,\
file_stat.st_gid
if info == 'mode':
return stat.S_IMODE(file_stat.st_mode)
if info == 'owner':
return file_stat.st_uid, file_stat.st_gid
def set_uid_gid_error(self, path, uid, gid, template_path=''):
def _chown_directory(self, target_path, chown_value):
"""Метод для смены владельца директории."""
try:
os.chown(target_path, chown_value['uid'], chown_value['gid'])
except (OSError, Exception) as error:
if not self._check_os_error(error, target_path):
raise TemplateExecutorError(
'Can not chown file: {0} to {1}, reason: {2}'.
format(target_path, self._translate_uid_gid(
target_path,
chown_value['uid'],
chown_value['gid']),
str(error)))
def _chmod_directory(self, target_path, chmod_value):
'''Метод для смены прав доступа к директории.'''
try:
os.chmod(target_path, chmod_value)
except (OSError, Exception) as error:
if not self._check_os_error(error, target_path):
self.output.set_error(
'Can not chmod directory: {0}, reason: {1}'.
format(target_path, str(error)))
def chown_file(self, target_path, chown_value, check_existation=True):
'''Метод для смены владельца файла.'''
try:
if check_existation and not os.path.exists(target_path):
open(target_path, 'w').close()
os.lchown(target_path, chown_value['uid'], chown_value['gid'])
except (OSError, Exception) as error:
if not self._check_os_error(error, target_path):
raise TemplateExecutorError(
'Can not chown file: {0} to {1}, reason: {2}'.
format(target_path, self._translate_uid_gid(
target_path,
chown_value['uid'],
chown_value['gid']),
str(error)))
def chmod_file(self, target_path, chmod_value, check_existation=True):
'''Метод для смены прав доступа к директории.'''
try:
if check_existation and not os.path.exists(target_path):
open(target_path, 'w').close()
os.chmod(target_path, chmod_value)
except (OSError, Exception) as error:
if not self._check_os_error(error, target_path):
raise TemplateExecutorError(
'Can not chmod file: {0}, reason: {1}'.
format(target_path, str(error)))
def _get_file_mode(self, file_path):
'''Метод для получения прав доступа для указанного файла.'''
file_stat = os.stat(file_path)
return stat.S_IMODE(file_stat.st_mode)
def _get_file_owner(self, file_path):
'''Метод для получения uid и gid значений для владельца указанного
файла.'''
file_stat = os.stat(file_path)
return {'uid': file_stat.st_uid, 'gid': file_stat.st_gid}
def _translate_uid_gid(self, target_path, uid, gid):
'''Метод для получения из uid и gid имен пользователя и группы при,
необходимых для выдачи сообщения об ошибке при попытке chown.'''
import pwd
import grp
try:
user_name = pwd.getpwuid(uid).pw_name
if self.chroot_path == '/':
user_name = pwd.getpwuid(uid).pw_name
else:
user_name = str(uid)
except (TypeError, KeyError):
user_name = str(uid)
try:
group_name = grp.getgrgid(gid).gr_name
if self.chroot_path == '/':
group_name = grp.getgrgid(gid).gr_name
else:
user_name = str(gid)
except (TypeError, KeyError):
group_name = str(gid)
owner = '{0}:{1}'.format(user_name, group_name)
if template_path:
self.output.set_error('Failed to process template file {}'.
template_path)
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !! описать ошибку !!
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
self.output.set_error('error with owner: {}'.format(owner))
def check_filesystem(self, target_path):
'''Метод, который предположительно будет использоваться для проверки
файловой системы перед применением шаблона.'''
pass
def is_vfat(self, path):
return '{0}:{1}'.format(user_name, group_name)
def _check_os_error(self, error, path_to_check):
'''Метод для проверки причины, по которой не удалось изменить владельца
или права доступа файла.'''
if hasattr(error, 'errno') and error.errno == os.errno.EPERM:
if self.is_vfat(path_to_check):
return True
return hasattr(error, 'errno') and error.errno == os.errno.EACCES and\
'var/calculate/remote' in path_to_check
def _is_vfat(self, path_to_check):
'''Метод, проверяющий является ли файловая система vfat. Нужно для того,
чтобы заранее знать о возможности применения chown, chmod и т.д.'''
чтобы знать о возможности применения chown, chmod и т.д.'''
# Инициализируем объект для проверки примонтированных файловых систем.
if self.mounts is None:
self.mounts = Mounts()
if self.mounts.get_from_fstab(what=self.mounts.TYPE,
where=self.mounts.DIR,
is_in=path) in ('vfat', 'ntfs-3g',
'ntfs'):
return True
return False
def check_os_error(self, error, path):
if hasattr(error, 'errno') and error.errno == os.errno.EPERM:
if self.is_vfat(path):
return True
if hasattr(error, 'errno') and error.errno == os.errno.EACCES and\
'var/calculate/remote' in path:
return True
return False
# Проверяем файловую систему на пути.
return self.mounts.get_from_fstab(what=self.mounts.TYPE,
where=self.mounts.DIR,
is_in=path_to_check) in {'vfat',
'ntfs-3g',
'ntfs'}
# Применение основного шаблона:

@ -1,11 +1,11 @@
import pytest
from calculate.templates.format.diff_format import DiffFormat
from calculate.templates.format.patch_format import PatchFormat
from calculate.utils.files import Process
from os import path
import os
@pytest.mark.diff
@pytest.mark.patch
class TestExecuteMethods:
def test_if_diff_patch_used_for_patching_of_several_files__it_changes_patched_file_correctly(self):
test_result = True
@ -13,7 +13,7 @@ class TestExecuteMethods:
with open(path.join(cwd_path, 'diff_1.patch')) as patch_file:
patch_text = patch_file.read()
diff_patch = DiffFormat(patch_text)
diff_patch = PatchFormat(patch_text)
print('Path:', cwd_path)
output = diff_patch.execute_format(target_path=cwd_path)
print('Output:')
@ -51,14 +51,14 @@ class TestExecuteMethods:
def test_if_diff_patch_used_for_patching_of_directories__it_changes_files_in_directories_and_adds_ones(self):
test_result = True
cwd_path = path.join(os.getcwd(),
'tests/templates/format/testfiles/a1')
'tests/templates/format/testfiles/a1')
patch_path = path.join(os.getcwd(),
'tests/templates/format/testfiles/diff_2.patch')
with open(path.join(patch_path)) as patch_file:
patch_text = patch_file.read()
diff_patch = DiffFormat(patch_text)
output = diff_patch.execute_format(target_path=cwd_path)
diff_patch = PatchFormat(patch_text)
diff_patch.execute_format(target_path=cwd_path)
for changed_file, change_type in\
diff_patch.changed_files.items():
@ -73,15 +73,18 @@ class TestExecuteMethods:
'b1', changed_file)
with open(other_file_path) as other_file:
other_file_text = other_file.read()
test_result = test_result and (other_file_text == patched_file_text)
print('test_result =', test_result)
test_result = test_result and (
other_file_text == patched_file_text)
print('test_result =', test_result)
if not test_result:
# print('Differences:')
print('Differences:')
try:
diff_process = Process('diff', '-u',
file_path,
other_file_path)
diff_result = diff_process.read()
# print(diff_result)
print(diff_result)
except Exception as error:
print('diff was not executed.')
print('Reason:', str(error))
@ -90,11 +93,10 @@ class TestExecuteMethods:
'-p{}'.format(diff_patch._last_level),
cwd=cwd_path)
reverse_patch_run.write(patch_text)
output = reverse_patch_run.read()
reverse_patch_run.read()
if reverse_patch_run.success():
print('[*] Changes was returned...')
else:
print('[!] Changes was not returned...')
assert test_result
assert False

@ -1,10 +1,10 @@
import pytest
from collections import OrderedDict
from calculate.templates.format.patch_format import PatchFormat
from calculate.templates.format.regex_format import RegexFormat
from calculate.templates.template_engine import ParametersContainer
@pytest.mark.patch
@pytest.mark.regex
class TestParsingMethods:
def test_if_input_patch_document_contains_only_regular_expressions_without_any_regex_flags__it_correctly_patches_input_document(self):
input_text = '''
@ -29,8 +29,8 @@ Another line of endless sadness.
<text>ParameterName = NewValue</text>
'''
patch_original = PatchFormat(input_text)
patch_template = PatchFormat(patch_text)
patch_original = RegexFormat(input_text)
patch_template = RegexFormat(patch_text)
patch_original.join_template(patch_template)
assert patch_original.document_text == output_text
@ -78,8 +78,8 @@ Another line of endless sadness.
parameters = ParametersContainer({'multiline': True, 'dotall': True})
patch_original = PatchFormat(input_text, parameters=parameters)
patch_template = PatchFormat(patch_text, parameters=parameters)
patch_original = RegexFormat(input_text, parameters=parameters)
patch_template = RegexFormat(patch_text, parameters=parameters)
patch_original.join_template(patch_template)
assert patch_original.document_text == output_text

@ -3,6 +3,7 @@ CONFIG_BUILDTIME_EXTABLE_SORT=y
#
# General setup
#
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_XZ=y

@ -1,11 +1,17 @@
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=16
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y

@ -1,6 +1,6 @@
diff -urN a/dir/file1.txt b/dir/file1.txt
--- a/dir/file1.txt 2020-01-29 14:38:21.216540100 +0300
+++ b/dir/file1.txt 2020-01-29 14:40:19.200542500 +0300
--- a/dir/file1.txt 2020-06-01 11:43:36.661218600 +0300
+++ b/dir/file1.txt 2020-02-06 12:49:10.941240900 +0300
@@ -1,10 +1,17 @@
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
@ -20,8 +20,8 @@ diff -urN a/dir/file1.txt b/dir/file1.txt
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
diff -urN a/dir/file2.txt b/dir/file2.txt
--- a/dir/file2.txt 2020-01-29 14:35:45.112536800 +0300
+++ b/dir/file2.txt 2020-01-29 13:47:05.475437800 +0300
--- a/dir/file2.txt 2020-06-01 11:43:36.693218600 +0300
+++ b/dir/file2.txt 2020-02-06 12:49:10.949240900 +0300
@@ -8,3 +8,9 @@
The old familiar sting
Try to kill it all away

@ -1,7 +1,7 @@
diff -Naru a1/dir/file1.txt b1/dir/file1.txt
--- a1/dir/file1.txt 2020-01-29 16:12:32.179927200 +0300
+++ b1/dir/file1.txt 2020-01-29 15:54:03.080863300 +0300
@@ -1,10 +1,17 @@
diff -Naur a1/dir/file1.txt b1/dir/file1.txt
--- a1/dir/file1.txt 2020-06-01 12:07:06.845725100 +0300
+++ b1/dir/file1.txt 2020-06-01 12:07:16.085725300 +0300
@@ -1,11 +1,17 @@
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y
+CONFIG_THREAD_INFO_IN_TASK=y
@ -12,16 +12,16 @@ diff -Naru a1/dir/file1.txt b1/dir/file1.txt
+# CONFIG_COMPILE_TEST is not set
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BUILD_SALT=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
diff -Naru a1/dir/file2.txt b1/dir/file2.txt
diff -Naur a1/dir/file2.txt b1/dir/file2.txt
--- a1/dir/file2.txt 1970-01-01 03:00:00.000000000 +0300
+++ b1/dir/file2.txt 2020-01-29 13:47:05.475437800 +0300
+++ b1/dir/file2.txt 2020-06-01 11:44:54.825220300 +0300
@@ -0,0 +1,16 @@
+Nine Inch Nails -- Hurt
+

@ -1,5 +0,0 @@
[section one]
parameter_1 = value
parameter_2 = value_2
[section two]
other_parameter = other_value

@ -1,3 +0,0 @@
dir /etc
dir /etc/dir
obj /etc/dir/file.conf 0b87fea7f5b65cac5012baa2bf647e72 1590764349

@ -1,5 +1,5 @@
[section one]
parameter_1 = value
parameter_2 = value_2
[section two]
other_parameter = other_value
parameter_1 = value_1
# Source file
[section_name]
rare_parameter = eternal_value

Loading…
Cancel
Save