diff --git a/calculate/templates/format/base_format.py b/calculate/templates/format/base_format.py index d782dbd..eb574bb 100644 --- a/calculate/templates/format/base_format.py +++ b/calculate/templates/format/base_format.py @@ -22,6 +22,8 @@ class Format: FORMAT = 'none' CALCULATE_VERSION = None + SHEBANG_PATTERN = r"^(?P#!\s*[\w\d\/]+\n)" + def __init__(self, processing_methods: List[Callable]): self._processing_methods = processing_methods self._document_dictionary = OrderedDict() @@ -355,24 +357,44 @@ class Format: def _get_header_and_document_text(self, input_text: str, template_path: str, - already_changed: bool = False + already_changed: bool = False, + check_shebang: bool = False ) -> Tuple[str, str]: '''Метод для создания заголовка измененного файла и удаления его из текста исходного файла.''' - header_pattern = self._get_header_pattern() template_paths = [] + + if check_shebang: + # Удаление #! + shebang_regex = re.compile(self.SHEBANG_PATTERN) + shebang_result = shebang_regex.search(input_text) + if shebang_result is not None: + print("string:", shebang_result.string) + print("groupdict:", shebang_result.groupdict()) + shebang = shebang_result.groupdict()['shebang'] + input_text = shebang_regex.sub("", input_text) + else: + shebang = "" + + header_pattern = self._get_header_pattern() header_regex = re.compile(header_pattern) parsing_result = header_regex.search(input_text) + if already_changed and self.comment_symbol and parsing_result: for template in parsing_result.\ groupdict()['template_paths'].strip().split('\n'): if template.startswith(self.comment_symbol): template = template[len(self.comment_symbol):] template_paths.append(template.strip()) + template_paths.append(template_path) header = self._make_header(template_paths) document_text = re.sub(header_pattern, '', input_text) - return header, document_text + + if check_shebang: + return header, document_text, shebang + else: + return header, document_text def _make_header(self, template_paths: list) -> str: if not self.comment_symbol: diff --git a/calculate/templates/format/raw_format.py b/calculate/templates/format/raw_format.py index dbac590..335c96c 100644 --- a/calculate/templates/format/raw_format.py +++ b/calculate/templates/format/raw_format.py @@ -21,18 +21,21 @@ class RawFormat(Format): self._before = join_before if add_header and not ignore_comments: - self.header, self._document_text =\ + self.header, self._document_text, self.shebang =\ self._get_header_and_document_text( document_text, template_path, - already_changed=already_changed) + already_changed=already_changed, + check_shebang=True) else: self.header = '' + self.shebang = '' self._document_text = document_text @property def document_text(self): - return '{}{}\n'.format(self.header, self._document_text) + return '{}{}{}\n'.format(self.shebang, self.header, + self._document_text) def join_template(self, template): if self._before: diff --git a/calculate/templates/format/regex_format.py b/calculate/templates/format/regex_format.py index ae81bf2..5edbfbc 100644 --- a/calculate/templates/format/regex_format.py +++ b/calculate/templates/format/regex_format.py @@ -34,13 +34,16 @@ class RegexFormat(Format): self._parsed_patch = None if add_header and not ignore_comments: - self.header, document_text = self._get_header_and_document_text( + self.header, self._document_text, self.shebang =\ + self._get_header_and_document_text( document_text, template_path, - already_changed=already_changed) + already_changed=already_changed, + check_shebang=True) else: self.header = '' - self._document_text = document_text + self.shebang = '' + self._document_text = document_text self._FLAG_VALUES = {'True': True, 'False': False, 'true': True, @@ -195,4 +198,4 @@ class RegexFormat(Format): @property def document_text(self): - return '{}{}'.format(self.header, self._document_text) + return '{}{}{}'.format(self.shebang, self.header, self._document_text) diff --git a/tests/templates/format/test_raw.py b/tests/templates/format/test_raw.py index fd11fd8..cb5b0c5 100644 --- a/tests/templates/format/test_raw.py +++ b/tests/templates/format/test_raw.py @@ -182,3 +182,63 @@ parameter-6 = f; original_2.join_template(template_2) assert original_2.document_text == output + + def test_shebang(self): + parameters = ParametersContainer({'comment': '#'}) + original_text = '''#!/bin/bash +echo "message_1"''' + + template_text_1 = '''echo "message_2" +exit 0''' + + output = '''#!/bin/bash +#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# path/to/template_1 +#------------------------------------------------------------------------------- +echo "message_1" +echo "message_2" +exit 0 +''' + + original_1 = RawFormat(original_text, 'path/to/template_1', + add_header=True, + already_changed=False, + parameters=parameters) + template_1 = RawFormat(template_text_1, 'path/to/template_1') + original_1.join_template(template_1) + assert original_1.document_text == output + + def test_shebang_and_comment(self): + parameters = ParametersContainer({'comment': '#'}) + original_text = '''#!/bin/bash +#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# path/to/ancient/template +#------------------------------------------------------------------------------- +echo "message_1"''' + + template_text_1 = '''echo "message_2" +exit 0''' + + output = '''#!/bin/bash +#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# path/to/ancient/template +# path/to/template_1 +#------------------------------------------------------------------------------- +echo "message_1" +echo "message_2" +exit 0 +''' + + original_1 = RawFormat(original_text, 'path/to/template_1', + add_header=True, + already_changed=True, + parameters=parameters) + template_1 = RawFormat(template_text_1, 'path/to/template_1') + original_1.join_template(template_1) + assert original_1.document_text == output diff --git a/tests/templates/format/test_regex.py b/tests/templates/format/test_regex.py index 152aaba..e956c40 100644 --- a/tests/templates/format/test_regex.py +++ b/tests/templates/format/test_regex.py @@ -387,3 +387,69 @@ Hello parameters=parameters) original_object.join_template(template_object) assert original_object.document_text == join_result + + def test_shebang(self): + parameters = ParametersContainer({'multiline': True, + 'dotall': True, + 'comment': '#'}) + original_text = '''echo "old message"''' + + template_text = r''' +old +new +\Z + +exit 0 +''' + + join_result = '''#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# /path/to/template +#------------------------------------------------------------------------------- +echo "new message" +exit 0''' + + original_object = RegexFormat(original_text, '/path/to/template', + add_header=True, already_changed=False, + parameters=parameters) + template_object = RegexFormat(template_text, '/path/to/template', + parameters=parameters) + original_object.join_template(template_object) + assert original_object.document_text == join_result + + def test_shebang_with_comment(self): + parameters = ParametersContainer({'multiline': True, + 'dotall': True, + 'comment': '#'}) + original_text = '''#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# /path/to/ancient/template +#------------------------------------------------------------------------------- +echo "old message"''' + + template_text = r''' +old +new +\Z + +exit 0 +''' + + join_result = '''#------------------------------------------------------------------------------- +# Modified by Calculate Utilities 4.0 +# Processed template files: +# /path/to/ancient/template +# /path/to/template +#------------------------------------------------------------------------------- +echo "new message" +exit 0''' + + original_object = RegexFormat(original_text, '/path/to/template', + add_header=True, already_changed=True, + parameters=parameters) + template_object = RegexFormat(template_text, '/path/to/template', + parameters=parameters) + original_object.join_template(template_object) + assert original_object.document_text == join_result diff --git a/tests/templates/test_directory_processor.py b/tests/templates/test_directory_processor.py index 59a177c..55fb51a 100644 --- a/tests/templates/test_directory_processor.py +++ b/tests/templates/test_directory_processor.py @@ -1683,37 +1683,39 @@ class TestDirectoryProcessor: assert (stat.st_uid, stat.st_gid) == (0, 0) def test_different_symbol_chmod_values_for_dirs_and_files(self): - datavars.main['cl_template_path'] = os.path.join(CHROOT_PATH, - 'templates_60') - mode = os.stat(join_paths(CHROOT_PATH, '/etc/dir_78')).st_mode - if mode != 0o40755: - os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78'), 0o40755) - - mode = os.stat(join_paths(CHROOT_PATH, - '/etc/dir_78/file_0')).st_mode - if mode != 0o100744: - os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78/file_0'), 0o100744) - - mode = os.stat(join_paths(CHROOT_PATH, - '/etc/dir_78/file_1')).st_mode - if mode != 0o100555: - os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78/file_1'), 0o100555) + if os.getuid() == 0: + datavars.main['cl_template_path'] = os.path.join(CHROOT_PATH, + 'templates_60') + mode = os.stat(join_paths(CHROOT_PATH, '/etc/dir_78')).st_mode + if mode != 0o40755: + os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78'), 0o40755) + + mode = os.stat(join_paths(CHROOT_PATH, + '/etc/dir_78/file_0')).st_mode + if mode != 0o100744: + os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78/file_0'), + 0o100744) + + mode = os.stat(join_paths(CHROOT_PATH, + '/etc/dir_78/file_1')).st_mode + if mode != 0o100555: + os.chmod(join_paths(CHROOT_PATH, '/etc/dir_78/file_1'), + 0o100555) - directory_processor = DirectoryProcessor('install', - datavars_module=datavars - ) - directory_processor.process_template_directories() + directory_processor = DirectoryProcessor('install', + datavars_module=datavars) + directory_processor.process_template_directories() - mode = os.stat(join_paths(CHROOT_PATH, '/etc/dir_78')).st_mode - assert int(mode) == 0o40655 + mode = os.stat(join_paths(CHROOT_PATH, '/etc/dir_78')).st_mode + assert int(mode) == 0o40655 - mode = os.stat(join_paths(CHROOT_PATH, - '/etc/dir_78/file_0')).st_mode - assert int(mode) == 0o100645 + mode = os.stat(join_paths(CHROOT_PATH, + '/etc/dir_78/file_0')).st_mode + assert int(mode) == 0o100645 - mode = os.stat(join_paths(CHROOT_PATH, - '/etc/dir_78/file_1')).st_mode - assert int(mode) == 0o100655 + mode = os.stat(join_paths(CHROOT_PATH, + '/etc/dir_78/file_1')).st_mode + assert int(mode) == 0o100655 def test_using_file_templates_from_base_directory(self): datavars.main['cl_template_path'] = os.path.join(CHROOT_PATH,