|
|
@ -43,7 +43,6 @@ from typing import (
|
|
|
|
List,
|
|
|
|
List,
|
|
|
|
Tuple,
|
|
|
|
Tuple,
|
|
|
|
Iterator,
|
|
|
|
Iterator,
|
|
|
|
NoReturn,
|
|
|
|
|
|
|
|
Optional,
|
|
|
|
Optional,
|
|
|
|
Callable
|
|
|
|
Callable
|
|
|
|
)
|
|
|
|
)
|
|
|
@ -123,21 +122,21 @@ class CalculateConfigFile:
|
|
|
|
self._unsaved_changes = False
|
|
|
|
self._unsaved_changes = False
|
|
|
|
return config_dictionary
|
|
|
|
return config_dictionary
|
|
|
|
|
|
|
|
|
|
|
|
def set_files_md5(self, file_path: str, file_md5: str) -> NoReturn:
|
|
|
|
def set_files_md5(self, file_path: str, file_md5: str) -> None:
|
|
|
|
'''Метод для установки в config соответствия файла некоторой
|
|
|
|
'''Метод для установки в config соответствия файла некоторой
|
|
|
|
контрольной сумме.'''
|
|
|
|
контрольной сумме.'''
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
self._config_dictionary[file_path] = file_md5
|
|
|
|
self._config_dictionary[file_path] = file_md5
|
|
|
|
self._unsaved_changes = True
|
|
|
|
self._unsaved_changes = True
|
|
|
|
|
|
|
|
|
|
|
|
def remove_file(self, file_path: str) -> NoReturn:
|
|
|
|
def remove_file(self, file_path: str) -> None:
|
|
|
|
'''Метод для удаления файла из config.'''
|
|
|
|
'''Метод для удаления файла из config.'''
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
if file_path in self._config_dictionary:
|
|
|
|
if file_path in self._config_dictionary:
|
|
|
|
self._config_dictionary.pop(file_path)
|
|
|
|
self._config_dictionary.pop(file_path)
|
|
|
|
self._unsaved_changes = True
|
|
|
|
self._unsaved_changes = True
|
|
|
|
|
|
|
|
|
|
|
|
def compare_md5(self, file_path: str, file_md5: str) -> NoReturn:
|
|
|
|
def compare_md5(self, file_path: str, file_md5: str) -> None:
|
|
|
|
'''Метод для сравнения хэш-суммы из config и некоторой заданной.'''
|
|
|
|
'''Метод для сравнения хэш-суммы из config и некоторой заданной.'''
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
file_path = self._remove_chroot(file_path)
|
|
|
|
if file_path in self._config_dictionary:
|
|
|
|
if file_path in self._config_dictionary:
|
|
|
@ -145,7 +144,7 @@ class CalculateConfigFile:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def save_changes(self) -> NoReturn:
|
|
|
|
def save_changes(self) -> None:
|
|
|
|
'''Метод для записи изменений, внессенных в файл config.'''
|
|
|
|
'''Метод для записи изменений, внессенных в файл config.'''
|
|
|
|
if not self._unsaved_changes:
|
|
|
|
if not self._unsaved_changes:
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -168,7 +167,6 @@ class CalculateConfigFile:
|
|
|
|
class TemplateWrapper:
|
|
|
|
class TemplateWrapper:
|
|
|
|
'''Класс связывающий шаблон с целевым файлом и определяющий параметры
|
|
|
|
'''Класс связывающий шаблон с целевым файлом и определяющий параметры
|
|
|
|
наложения шаблона, обусловленные состоянием целевого файла.'''
|
|
|
|
наложения шаблона, обусловленные состоянием целевого файла.'''
|
|
|
|
|
|
|
|
|
|
|
|
type_checks: Dict[int,
|
|
|
|
type_checks: Dict[int,
|
|
|
|
Callable[[str], bool]] = {DIR: os.path.isdir,
|
|
|
|
Callable[[str], bool]] = {DIR: os.path.isdir,
|
|
|
|
FILE: os.path.isfile}
|
|
|
|
FILE: os.path.isfile}
|
|
|
@ -264,7 +262,7 @@ class TemplateWrapper:
|
|
|
|
raise TemplateExecutorError("'format' parameter is not set"
|
|
|
|
raise TemplateExecutorError("'format' parameter is not set"
|
|
|
|
" file template.")
|
|
|
|
" file template.")
|
|
|
|
|
|
|
|
|
|
|
|
# Если по этому пути что-то есть -- проверяем конфликты.
|
|
|
|
# Если по этому пути что-то есть -- проверяем тип этого.
|
|
|
|
if os.path.exists(target_file_path):
|
|
|
|
if os.path.exists(target_file_path):
|
|
|
|
for file_type, checker in self.type_checks.items():
|
|
|
|
for file_type, checker in self.type_checks.items():
|
|
|
|
if checker(target_file_path):
|
|
|
|
if checker(target_file_path):
|
|
|
@ -312,7 +310,7 @@ class TemplateWrapper:
|
|
|
|
# self.parameters.append == "replace"):
|
|
|
|
# self.parameters.append == "replace"):
|
|
|
|
# self.remove_original = True
|
|
|
|
# self.remove_original = True
|
|
|
|
|
|
|
|
|
|
|
|
def _check_type_conflicts(self) -> NoReturn:
|
|
|
|
def _check_type_conflicts(self) -> None:
|
|
|
|
'''Метод для проверки конфликтов типов.'''
|
|
|
|
'''Метод для проверки конфликтов типов.'''
|
|
|
|
if self.parameters.append == 'link':
|
|
|
|
if self.parameters.append == 'link':
|
|
|
|
if self.parameters.force:
|
|
|
|
if self.parameters.force:
|
|
|
@ -386,7 +384,7 @@ class TemplateWrapper:
|
|
|
|
raise TemplateTypeConflict("the target file is a directory"
|
|
|
|
raise TemplateTypeConflict("the target file is a directory"
|
|
|
|
" while the template is a file")
|
|
|
|
" while the template is a file")
|
|
|
|
|
|
|
|
|
|
|
|
def _check_package_collision(self) -> NoReturn:
|
|
|
|
def _check_package_collision(self) -> None:
|
|
|
|
'''Метод для проверки на предмет коллизии, то есть конфликта пакета
|
|
|
|
'''Метод для проверки на предмет коллизии, то есть конфликта пакета
|
|
|
|
шаблона и целевого файла.'''
|
|
|
|
шаблона и целевого файла.'''
|
|
|
|
if self.parameters.package:
|
|
|
|
if self.parameters.package:
|
|
|
@ -475,7 +473,9 @@ class TemplateWrapper:
|
|
|
|
def _compare_packages(self, lpackage: PackageAtomName,
|
|
|
|
def _compare_packages(self, lpackage: PackageAtomName,
|
|
|
|
rpackage: PackageAtomName
|
|
|
|
rpackage: PackageAtomName
|
|
|
|
) -> Union[None, PackageAtomName]:
|
|
|
|
) -> Union[None, PackageAtomName]:
|
|
|
|
'''Метод, сравнивающий пакеты по их именам, возвращает старший.'''
|
|
|
|
'''Метод, сравнивающий пакеты по их именам, возвращает старший, если
|
|
|
|
|
|
|
|
пакеты с одинаковыми именами, но разными версиями, или None, если их
|
|
|
|
|
|
|
|
имена и категории не равны.'''
|
|
|
|
if lpackage.category != rpackage.category:
|
|
|
|
if lpackage.category != rpackage.category:
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
@ -487,7 +487,7 @@ class TemplateWrapper:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return rpackage
|
|
|
|
return rpackage
|
|
|
|
|
|
|
|
|
|
|
|
def _check_user_changes(self) -> NoReturn:
|
|
|
|
def _check_user_changes(self) -> None:
|
|
|
|
'''Метод для проверки наличия пользовательских изменений в
|
|
|
|
'''Метод для проверки наличия пользовательских изменений в
|
|
|
|
конфигурационных файлах.'''
|
|
|
|
конфигурационных файлах.'''
|
|
|
|
# Эта проверка только для файлов.
|
|
|
|
# Эта проверка только для файлов.
|
|
|
@ -520,8 +520,7 @@ class TemplateWrapper:
|
|
|
|
# Путь к архивной версии файла.
|
|
|
|
# Путь к архивной версии файла.
|
|
|
|
self.archive_path = self._get_archive_path(self.target_path)
|
|
|
|
self.archive_path = self._get_archive_path(self.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
self.contents_matching = (self.parameters.autoupdate
|
|
|
|
self.contents_matching = (self.parameters.autoupdate)
|
|
|
|
or self.parameters.force)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not self.protected:
|
|
|
|
if not self.protected:
|
|
|
|
self.contents_matching = True
|
|
|
|
self.contents_matching = True
|
|
|
@ -545,6 +544,8 @@ class TemplateWrapper:
|
|
|
|
# Если файл по целевому пути не относится к какому-либо пакету.
|
|
|
|
# Если файл по целевому пути не относится к какому-либо пакету.
|
|
|
|
# self.contents_matching = False
|
|
|
|
# self.contents_matching = False
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
elif self.target_type is DIR and self.parameters.force:
|
|
|
|
|
|
|
|
self.contents_matching = True
|
|
|
|
elif not self.contents_matching:
|
|
|
|
elif not self.contents_matching:
|
|
|
|
# Если файл есть и он относится к текущему пакету.
|
|
|
|
# Если файл есть и он относится к текущему пакету.
|
|
|
|
# Если по каким-то причинам уже нужно считать, что хэш-суммы
|
|
|
|
# Если по каким-то причинам уже нужно считать, что хэш-суммы
|
|
|
@ -613,7 +614,7 @@ class TemplateWrapper:
|
|
|
|
|
|
|
|
|
|
|
|
return new_cfg_path
|
|
|
|
return new_cfg_path
|
|
|
|
|
|
|
|
|
|
|
|
def remove_from_contents(self) -> NoReturn:
|
|
|
|
def remove_from_contents(self) -> None:
|
|
|
|
'''Метод для удаления целевого файла из CONTENTS.'''
|
|
|
|
'''Метод для удаления целевого файла из CONTENTS.'''
|
|
|
|
if self.target_package is None:
|
|
|
|
if self.target_package is None:
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -623,13 +624,13 @@ class TemplateWrapper:
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
self.target_package.remove_obj(self.target_path)
|
|
|
|
self.target_package.remove_obj(self.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
def clear_dir_contents(self) -> NoReturn:
|
|
|
|
def clear_dir_contents(self) -> None:
|
|
|
|
'''Метод для удаления из CONTENTS всего содержимого директории после
|
|
|
|
'''Метод для удаления из CONTENTS всего содержимого директории после
|
|
|
|
применения append = "clear".'''
|
|
|
|
применения append = "clear".'''
|
|
|
|
if self.template_type == DIR and self.target_package is not None:
|
|
|
|
if self.template_type == DIR and self.target_package is not None:
|
|
|
|
self.target_package.clear_dir(self.target_path)
|
|
|
|
self.target_package.clear_dir(self.target_path)
|
|
|
|
|
|
|
|
|
|
|
|
def add_to_contents(self, file_md5: Optional[str] = None) -> NoReturn:
|
|
|
|
def add_to_contents(self, file_md5: Optional[str] = None) -> None:
|
|
|
|
'''Метод для добавления целевого файла в CONTENTS.'''
|
|
|
|
'''Метод для добавления целевого файла в CONTENTS.'''
|
|
|
|
if self.target_package is None:
|
|
|
|
if self.target_package is None:
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -652,7 +653,7 @@ class TemplateWrapper:
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
elif self.template_type == FILE:
|
|
|
|
self.target_package.add_obj(source_path, file_md5=file_md5)
|
|
|
|
self.target_package.add_obj(source_path, file_md5=file_md5)
|
|
|
|
|
|
|
|
|
|
|
|
def update_contents_from_list(self, changed_list: dict) -> NoReturn:
|
|
|
|
def update_contents_from_list(self, changed_list: dict) -> None:
|
|
|
|
'''Метод для изменения CONTENTS по списку измененных файлов.'''
|
|
|
|
'''Метод для изменения CONTENTS по списку измененных файлов.'''
|
|
|
|
print("UPDATE CONTENTS FROM LIST")
|
|
|
|
print("UPDATE CONTENTS FROM LIST")
|
|
|
|
if self.target_package is None:
|
|
|
|
if self.target_package is None:
|
|
|
@ -676,7 +677,7 @@ class TemplateWrapper:
|
|
|
|
self.target_package.add_dir(file_path)
|
|
|
|
self.target_package.add_dir(file_path)
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
@classmethod
|
|
|
|
def _set_protected(cls, chroot_path: str) -> NoReturn:
|
|
|
|
def _set_protected(cls, chroot_path: str) -> None:
|
|
|
|
'''Метод для получения множества защищенных директорий.'''
|
|
|
|
'''Метод для получения множества защищенных директорий.'''
|
|
|
|
cls._protected_set = set()
|
|
|
|
cls._protected_set = set()
|
|
|
|
cls._unprotected_set = set()
|
|
|
|
cls._unprotected_set = set()
|
|
|
@ -699,7 +700,7 @@ class TemplateWrapper:
|
|
|
|
|
|
|
|
|
|
|
|
cls._protected_is_set = True
|
|
|
|
cls._protected_is_set = True
|
|
|
|
|
|
|
|
|
|
|
|
def save_changes(self) -> NoReturn:
|
|
|
|
def save_changes(self) -> None:
|
|
|
|
'''Метод для сохранения изменений внесенных в CONTENTS.'''
|
|
|
|
'''Метод для сохранения изменений внесенных в CONTENTS.'''
|
|
|
|
if self.target_package:
|
|
|
|
if self.target_package:
|
|
|
|
self.target_package.remove_empty_directories()
|
|
|
|
self.target_package.remove_empty_directories()
|
|
|
@ -864,7 +865,7 @@ class TemplateExecutor:
|
|
|
|
|
|
|
|
|
|
|
|
return self.executor_output
|
|
|
|
return self.executor_output
|
|
|
|
|
|
|
|
|
|
|
|
def save_changes(self) -> NoReturn:
|
|
|
|
def save_changes(self) -> None:
|
|
|
|
'''Метод для сохранения чего-нибудь после выполнения всех шаблонов.'''
|
|
|
|
'''Метод для сохранения чего-нибудь после выполнения всех шаблонов.'''
|
|
|
|
# Пока сохраняем только получившееся содержимое config-файла.
|
|
|
|
# Пока сохраняем только получившееся содержимое config-файла.
|
|
|
|
self.calculate_config_file.save_changes()
|
|
|
|
self.calculate_config_file.save_changes()
|
|
|
@ -892,7 +893,7 @@ class TemplateExecutor:
|
|
|
|
template_object.add_to_contents()
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_remove_directory(self, template_object: TemplateWrapper
|
|
|
|
def _append_remove_directory(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия для append = "remove", если шаблон --
|
|
|
|
'''Метод описывающий действия для append = "remove", если шаблон --
|
|
|
|
директория. Удаляет директорию со всем содержимым, если она есть.'''
|
|
|
|
директория. Удаляет директорию со всем содержимым, если она есть.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
@ -914,11 +915,11 @@ class TemplateExecutor:
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_skip_directory(self,
|
|
|
|
def _append_skip_directory(self,
|
|
|
|
template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
template_object: TemplateWrapper) -> None:
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def _append_clear_directory(self,
|
|
|
|
def _append_clear_directory(self,
|
|
|
|
template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод описывающий действия для append = "clear", если шаблон --
|
|
|
|
'''Метод описывающий действия для append = "clear", если шаблон --
|
|
|
|
директория. Удаляет все содержимое директории, если она есть.'''
|
|
|
|
директория. Удаляет все содержимое директории, если она есть.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
@ -949,7 +950,7 @@ class TemplateExecutor:
|
|
|
|
template_object.clear_dir_contents()
|
|
|
|
template_object.clear_dir_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_link_directory(self, template_object: TemplateWrapper
|
|
|
|
def _append_link_directory(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия для append = "link", если шаблон --
|
|
|
|
'''Метод описывающий действия для append = "link", если шаблон --
|
|
|
|
директория. Создает ссылку на директорию, если она есть.'''
|
|
|
|
директория. Создает ссылку на директорию, если она есть.'''
|
|
|
|
self._link_directory(template_object.parameters.source,
|
|
|
|
self._link_directory(template_object.parameters.source,
|
|
|
@ -974,7 +975,7 @@ class TemplateExecutor:
|
|
|
|
template_object.add_to_contents()
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_replace_directory(self, template_object: TemplateWrapper
|
|
|
|
def _append_replace_directory(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия для append = "replace", если шаблон --
|
|
|
|
'''Метод описывающий действия для append = "replace", если шаблон --
|
|
|
|
директория. Очищает директорию или создает, если ее нет.'''
|
|
|
|
директория. Очищает директорию или создает, если ее нет.'''
|
|
|
|
if template_object.target_type is None:
|
|
|
|
if template_object.target_type is None:
|
|
|
@ -1006,7 +1007,7 @@ class TemplateExecutor:
|
|
|
|
|
|
|
|
|
|
|
|
def _append_join_file(self, template_object: TemplateWrapper,
|
|
|
|
def _append_join_file(self, template_object: TemplateWrapper,
|
|
|
|
join_before: bool = False, replace: bool = False
|
|
|
|
join_before: bool = False, replace: bool = False
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия при append = "join", если шаблон -- файл.
|
|
|
|
'''Метод описывающий действия при append = "join", если шаблон -- файл.
|
|
|
|
Объединяет шаблон с целевым файлом.'''
|
|
|
|
Объединяет шаблон с целевым файлом.'''
|
|
|
|
output_path = template_object.output_path
|
|
|
|
output_path = template_object.output_path
|
|
|
@ -1105,6 +1106,7 @@ class TemplateExecutor:
|
|
|
|
chroot_path=self.chroot_path)
|
|
|
|
chroot_path=self.chroot_path)
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
# Удаляем форматный объект входного файла.
|
|
|
|
# del(parsed_template)
|
|
|
|
# del(parsed_template)
|
|
|
|
|
|
|
|
|
|
|
|
# Если исполняемый формат выдал список измененных файлов для
|
|
|
|
# Если исполняемый формат выдал список измененных файлов для
|
|
|
|
# изменения CONTENTS и при этом задан пакет -- обновляем
|
|
|
|
# изменения CONTENTS и при этом задан пакет -- обновляем
|
|
|
|
# CONTENTS.
|
|
|
|
# CONTENTS.
|
|
|
@ -1279,32 +1281,32 @@ class TemplateExecutor:
|
|
|
|
chown = self.file_default_parameters.get('chown', False)
|
|
|
|
chown = self.file_default_parameters.get('chown', False)
|
|
|
|
return chown
|
|
|
|
return chown
|
|
|
|
|
|
|
|
|
|
|
|
def _append_after_file(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _append_after_file(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
в конец файла и в конец каждой секции файла.'''
|
|
|
|
в конец файла и в конец каждой секции файла.'''
|
|
|
|
self._append_join_file(template_object, join_before=False)
|
|
|
|
self._append_join_file(template_object, join_before=False)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_before_file(self, template_object: TemplateWrapper
|
|
|
|
def _append_before_file(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "after", если шаблон --
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
файл. Объединяет шаблон с целевым файлом так, чтобы текст добавлялся
|
|
|
|
в начало файла и в начало каждой секции файла.'''
|
|
|
|
в начало файла и в начало каждой секции файла.'''
|
|
|
|
self._append_join_file(template_object, join_before=True)
|
|
|
|
self._append_join_file(template_object, join_before=True)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_skip_file(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _append_skip_file(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод описывающий действия при append = "skip". Пока никаких
|
|
|
|
'''Метод описывающий действия при append = "skip". Пока никаких
|
|
|
|
действий.'''
|
|
|
|
действий.'''
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def _append_replace_file(self, template_object: TemplateWrapper
|
|
|
|
def _append_replace_file(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия при append = "replace", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "replace", если шаблон --
|
|
|
|
файл. Очищает файл и затем накладывает на него шаблон.'''
|
|
|
|
файл. Очищает файл и затем накладывает на него шаблон.'''
|
|
|
|
self._append_join_file(template_object, replace=True)
|
|
|
|
self._append_join_file(template_object, replace=True)
|
|
|
|
|
|
|
|
|
|
|
|
def _append_remove_file(self, template_object: TemplateWrapper
|
|
|
|
def _append_remove_file(self, template_object: TemplateWrapper
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
'''Метод описывающий действия при append = "remove", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "remove", если шаблон --
|
|
|
|
файл. Удаляет файл.'''
|
|
|
|
файл. Удаляет файл.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
@ -1320,7 +1322,7 @@ class TemplateExecutor:
|
|
|
|
if self.dbpkg:
|
|
|
|
if self.dbpkg:
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
template_object.remove_from_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_clear_file(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _append_clear_file(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод описывающий действия при append = "clear", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "clear", если шаблон --
|
|
|
|
файл. Очищает файл.'''
|
|
|
|
файл. Очищает файл.'''
|
|
|
|
if template_object.target_type is not None:
|
|
|
|
if template_object.target_type is not None:
|
|
|
@ -1342,7 +1344,7 @@ class TemplateExecutor:
|
|
|
|
if self.dbpkg:
|
|
|
|
if self.dbpkg:
|
|
|
|
template_object.add_to_contents()
|
|
|
|
template_object.add_to_contents()
|
|
|
|
|
|
|
|
|
|
|
|
def _append_link_file(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _append_link_file(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод описывающий действия при append = "link", если шаблон --
|
|
|
|
'''Метод описывающий действия при append = "link", если шаблон --
|
|
|
|
файл. Создает ссылку на файл, указанный в параметре source.'''
|
|
|
|
файл. Создает ссылку на файл, указанный в параметре source.'''
|
|
|
|
input_path = template_object.input_path
|
|
|
|
input_path = template_object.input_path
|
|
|
@ -1424,7 +1426,7 @@ class TemplateExecutor:
|
|
|
|
return hashlib.md5(source_path.encode()).hexdigest()
|
|
|
|
return hashlib.md5(source_path.encode()).hexdigest()
|
|
|
|
|
|
|
|
|
|
|
|
def _create_directory(self, template_object: TemplateWrapper,
|
|
|
|
def _create_directory(self, template_object: TemplateWrapper,
|
|
|
|
path_to_create: Optional[str] = None) -> NoReturn:
|
|
|
|
path_to_create: Optional[str] = None) -> None:
|
|
|
|
'''Метод для создания директории и, при необходимости, изменения
|
|
|
|
'''Метод для создания директории и, при необходимости, изменения
|
|
|
|
владельца и доступа все директорий на пути к целевой.'''
|
|
|
|
владельца и доступа все директорий на пути к целевой.'''
|
|
|
|
if path_to_create is None:
|
|
|
|
if path_to_create is None:
|
|
|
@ -1481,7 +1483,7 @@ class TemplateExecutor:
|
|
|
|
'Failed to create directory: {}, reason: {}'.
|
|
|
|
'Failed to create directory: {}, reason: {}'.
|
|
|
|
format(create_path, str(error)))
|
|
|
|
format(create_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _remove_directory(self, target_path: str) -> NoReturn:
|
|
|
|
def _remove_directory(self, target_path: str) -> None:
|
|
|
|
'''Метод для удаления директории.'''
|
|
|
|
'''Метод для удаления директории.'''
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
@ -1505,7 +1507,7 @@ class TemplateExecutor:
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
error_message))
|
|
|
|
error_message))
|
|
|
|
|
|
|
|
|
|
|
|
def _clear_directory(self, target_path: str) -> NoReturn:
|
|
|
|
def _clear_directory(self, target_path: str) -> None:
|
|
|
|
'''Метод для очистки содержимого целевой директории.'''
|
|
|
|
'''Метод для очистки содержимого целевой директории.'''
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
|
if os.path.isdir(target_path):
|
|
|
@ -1526,9 +1528,9 @@ class TemplateExecutor:
|
|
|
|
error_message))
|
|
|
|
error_message))
|
|
|
|
|
|
|
|
|
|
|
|
def _link_directory(self, source: str, target_path: str,
|
|
|
|
def _link_directory(self, source: str, target_path: str,
|
|
|
|
force: bool = False) -> NoReturn:
|
|
|
|
force: bool = False) -> None:
|
|
|
|
'''Метод для создания по целевому пути ссылки на директорию
|
|
|
|
'''Метод для создания по целевому пути ссылки на директорию
|
|
|
|
расположенную на пути, указанному в source.'''
|
|
|
|
расположенную на пути, указанном в source.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
os.symlink(source, target_path, target_is_directory=True)
|
|
|
|
os.symlink(source, target_path, target_is_directory=True)
|
|
|
|
except OSError as error:
|
|
|
|
except OSError as error:
|
|
|
@ -1536,7 +1538,7 @@ class TemplateExecutor:
|
|
|
|
"failed to create symlink: {0} -> {1}, reason: {2}".
|
|
|
|
"failed to create symlink: {0} -> {1}, reason: {2}".
|
|
|
|
format(target_path, source, str(error)))
|
|
|
|
format(target_path, source, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _remove_file(self, target_path: str) -> NoReturn:
|
|
|
|
def _remove_file(self, target_path: str) -> None:
|
|
|
|
'''Метод для удаления файлов.'''
|
|
|
|
'''Метод для удаления файлов.'''
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.isfile(target_path):
|
|
|
|
if os.path.isfile(target_path):
|
|
|
@ -1567,7 +1569,7 @@ class TemplateExecutor:
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
error_message))
|
|
|
|
error_message))
|
|
|
|
|
|
|
|
|
|
|
|
def _clear_file(self, target_path: str) -> NoReturn:
|
|
|
|
def _clear_file(self, target_path: str) -> None:
|
|
|
|
'''Метод для очистки файлов.'''
|
|
|
|
'''Метод для очистки файлов.'''
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.isfile(target_path):
|
|
|
|
if os.path.isfile(target_path):
|
|
|
@ -1586,7 +1588,7 @@ class TemplateExecutor:
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
"reason: {1}").format(target_path,
|
|
|
|
error_message))
|
|
|
|
error_message))
|
|
|
|
|
|
|
|
|
|
|
|
def _link_file(self, source: str, target_path: str) -> NoReturn:
|
|
|
|
def _link_file(self, source: str, target_path: str) -> None:
|
|
|
|
'''Метод для создания по целевому пути ссылки на файл расположенный на
|
|
|
|
'''Метод для создания по целевому пути ссылки на файл расположенный на
|
|
|
|
пути, указанному в source.'''
|
|
|
|
пути, указанному в source.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -1596,7 +1598,7 @@ class TemplateExecutor:
|
|
|
|
"failed to create symlink to the file: {0} -> {1}, reason: {2}".
|
|
|
|
"failed to create symlink to the file: {0} -> {1}, reason: {2}".
|
|
|
|
format(target_path, source, str(error)))
|
|
|
|
format(target_path, source, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _run_template(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _run_template(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
интерпретатором указанным в run прямо во время обработки шаблонов.'''
|
|
|
|
интерпретатором указанным в run прямо во время обработки шаблонов.'''
|
|
|
|
text_to_run = template_object.template_text
|
|
|
|
text_to_run = template_object.template_text
|
|
|
@ -1634,7 +1636,7 @@ class TemplateExecutor:
|
|
|
|
" interpreter '{}', reason: {}").
|
|
|
|
" interpreter '{}', reason: {}").
|
|
|
|
format(interpreter, str(error)))
|
|
|
|
format(interpreter, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _exec_template(self, template_object: TemplateWrapper) -> NoReturn:
|
|
|
|
def _exec_template(self, template_object: TemplateWrapper) -> None:
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
'''Метод для сохранения текста шаблонов, который должен быть исполнен
|
|
|
|
интерпретатором указанным в exec после выполнения всех прочих шаблонов.
|
|
|
|
интерпретатором указанным в exec после выполнения всех прочих шаблонов.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
@ -1720,7 +1722,7 @@ class TemplateExecutor:
|
|
|
|
format(interpreter, str(error)))
|
|
|
|
format(interpreter, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _chown_directory(self, target_path: str, chown_value: dict
|
|
|
|
def _chown_directory(self, target_path: str, chown_value: dict
|
|
|
|
) -> NoReturn:
|
|
|
|
) -> None:
|
|
|
|
"""Метод для смены владельца директории."""
|
|
|
|
"""Метод для смены владельца директории."""
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
@ -1738,7 +1740,7 @@ class TemplateExecutor:
|
|
|
|
chown_value['gid']),
|
|
|
|
chown_value['gid']),
|
|
|
|
str(error)))
|
|
|
|
str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _chmod_directory(self, target_path: str, chmod_value: int) -> NoReturn:
|
|
|
|
def _chmod_directory(self, target_path: str, chmod_value: int) -> None:
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
if isinstance(chmod_value, tuple) and not chmod_value[1]:
|
|
|
|
if isinstance(chmod_value, tuple) and not chmod_value[1]:
|
|
|
|
chmod_value = chmod_value[0]
|
|
|
|
chmod_value = chmod_value[0]
|
|
|
@ -1759,7 +1761,7 @@ class TemplateExecutor:
|
|
|
|
'Can not chmod directory: {0}, reason: {1}'.
|
|
|
|
'Can not chmod directory: {0}, reason: {1}'.
|
|
|
|
format(target_path, str(error)))
|
|
|
|
format(target_path, str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _chown_file(self, target_path: str, chown_value: dict) -> NoReturn:
|
|
|
|
def _chown_file(self, target_path: str, chown_value: dict) -> None:
|
|
|
|
'''Метод для смены владельца файла.'''
|
|
|
|
'''Метод для смены владельца файла.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
if os.path.exists(target_path):
|
|
|
|
if os.path.exists(target_path):
|
|
|
@ -1777,7 +1779,7 @@ class TemplateExecutor:
|
|
|
|
chown_value['gid']),
|
|
|
|
chown_value['gid']),
|
|
|
|
str(error)))
|
|
|
|
str(error)))
|
|
|
|
|
|
|
|
|
|
|
|
def _chmod_file(self, target_path: str, chmod_value: int) -> NoReturn:
|
|
|
|
def _chmod_file(self, target_path: str, chmod_value: int) -> None:
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
'''Метод для смены прав доступа к директории.'''
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
if not os.path.exists(target_path):
|
|
|
|
if not os.path.exists(target_path):
|
|
|
@ -1802,13 +1804,15 @@ class TemplateExecutor:
|
|
|
|
current_mode: Optional[int] = None) -> int:
|
|
|
|
current_mode: Optional[int] = None) -> int:
|
|
|
|
'''Метод для наложения X-маски, необходимой для получения значения
|
|
|
|
'''Метод для наложения X-маски, необходимой для получения значения
|
|
|
|
chmod, c учетом возможности наличия в нем значения "X".'''
|
|
|
|
chmod, c учетом возможности наличия в нем значения "X".'''
|
|
|
|
if not chmod[1]:
|
|
|
|
chmod, x_mask = chmod
|
|
|
|
return chmod[0]
|
|
|
|
|
|
|
|
|
|
|
|
if not x_mask:
|
|
|
|
|
|
|
|
return chmod
|
|
|
|
|
|
|
|
|
|
|
|
if current_mode is None:
|
|
|
|
if current_mode is None:
|
|
|
|
return chmod[0] ^ chmod[1]
|
|
|
|
return chmod ^ x_mask
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return chmod[0] ^ (current_mode & chmod[1])
|
|
|
|
return chmod ^ (current_mode & x_mask)
|
|
|
|
|
|
|
|
|
|
|
|
def _get_file_mode(self, file_path: str) -> int:
|
|
|
|
def _get_file_mode(self, file_path: str) -> int:
|
|
|
|
'''Метод для получения прав доступа для указанного файла.'''
|
|
|
|
'''Метод для получения прав доступа для указанного файла.'''
|
|
|
@ -1847,7 +1851,7 @@ class TemplateExecutor:
|
|
|
|
if self.chroot_path == '/':
|
|
|
|
if self.chroot_path == '/':
|
|
|
|
group_name = grp.getgrgid(gid).gr_name
|
|
|
|
group_name = grp.getgrgid(gid).gr_name
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
group_name = self._get_group_name_form_gid(gid)
|
|
|
|
group_name = self._get_group_name_from_gid(gid)
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
except (TypeError, KeyError):
|
|
|
|
group_name = str(gid)
|
|
|
|
group_name = str(gid)
|
|
|
|
|
|
|
|
|
|
|
@ -1875,7 +1879,7 @@ class TemplateExecutor:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return str(uid)
|
|
|
|
return str(uid)
|
|
|
|
|
|
|
|
|
|
|
|
def _get_group_name_form_gid(self, gid: int) -> str:
|
|
|
|
def _get_group_name_from_gid(self, gid: int) -> str:
|
|
|
|
'''Метод для получения названия группы по его gid.'''
|
|
|
|
'''Метод для получения названия группы по его gid.'''
|
|
|
|
group_file_path = os.path.join(self.chroot_path, 'etc/group')
|
|
|
|
group_file_path = os.path.join(self.chroot_path, 'etc/group')
|
|
|
|
group_dictionary = dict()
|
|
|
|
group_dictionary = dict()
|
|
|
@ -1927,7 +1931,7 @@ class DirectoryTree:
|
|
|
|
self.base_directory = base_directory
|
|
|
|
self.base_directory = base_directory
|
|
|
|
self._tree = {}
|
|
|
|
self._tree = {}
|
|
|
|
|
|
|
|
|
|
|
|
def update_tree(self, tree: dict) -> NoReturn:
|
|
|
|
def update_tree(self, tree: dict) -> None:
|
|
|
|
'''Метод, инициирующий наложение заданного дерева каталогов на данный
|
|
|
|
'''Метод, инициирующий наложение заданного дерева каталогов на данный
|
|
|
|
экземпляр дерева.'''
|
|
|
|
экземпляр дерева.'''
|
|
|
|
self._update(self._tree, tree)
|
|
|
|
self._update(self._tree, tree)
|
|
|
@ -1943,7 +1947,7 @@ class DirectoryTree:
|
|
|
|
original_tree[parent] = child
|
|
|
|
original_tree[parent] = child
|
|
|
|
return original_tree
|
|
|
|
return original_tree
|
|
|
|
|
|
|
|
|
|
|
|
def show_tree(self) -> NoReturn:
|
|
|
|
def show_tree(self) -> None:
|
|
|
|
pprint(self._tree)
|
|
|
|
pprint(self._tree)
|
|
|
|
|
|
|
|
|
|
|
|
def get_directory_tree(self, directory: str) -> "DirectoryTree":
|
|
|
|
def get_directory_tree(self, directory: str) -> "DirectoryTree":
|
|
|
@ -1956,13 +1960,13 @@ class DirectoryTree:
|
|
|
|
directory_tree._tree = self._tree[directory]
|
|
|
|
directory_tree._tree = self._tree[directory]
|
|
|
|
return directory_tree
|
|
|
|
return directory_tree
|
|
|
|
|
|
|
|
|
|
|
|
def __getitem__(self, name: str) -> dict:
|
|
|
|
def __getitem__(self, name: str) -> Union[None, dict]:
|
|
|
|
if name in self._tree:
|
|
|
|
if name in self._tree:
|
|
|
|
return self._tree[name]
|
|
|
|
return self._tree[name]
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def __setitem__(self, name: str, value: Union[None, dict]) -> NoReturn:
|
|
|
|
def __setitem__(self, name: str, value: Union[None, dict]) -> None:
|
|
|
|
self._tree[name] = value
|
|
|
|
self._tree[name] = value
|
|
|
|
|
|
|
|
|
|
|
|
def __iter__(self) -> Iterator[str]:
|
|
|
|
def __iter__(self) -> Iterator[str]:
|
|
|
@ -2149,7 +2153,7 @@ class DirectoryProcessor:
|
|
|
|
return path_to_add
|
|
|
|
return path_to_add
|
|
|
|
|
|
|
|
|
|
|
|
def _add_package_to_group(self, group_name: str,
|
|
|
|
def _add_package_to_group(self, group_name: str,
|
|
|
|
package_atom: str) -> NoReturn:
|
|
|
|
package_atom: str) -> None:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
groups_namespace = self.datavars_module.main.cl.groups
|
|
|
|
groups_namespace = self.datavars_module.main.cl.groups
|
|
|
|
except (VariableNotFoundError, AttributeError):
|
|
|
|
except (VariableNotFoundError, AttributeError):
|
|
|
@ -2230,7 +2234,7 @@ class DirectoryProcessor:
|
|
|
|
return -1
|
|
|
|
return -1
|
|
|
|
return -2
|
|
|
|
return -2
|
|
|
|
|
|
|
|
|
|
|
|
def _make_current_template_var(self) -> NoReturn:
|
|
|
|
def _make_current_template_var(self) -> None:
|
|
|
|
var_path = ['main', 'cl']
|
|
|
|
var_path = ['main', 'cl']
|
|
|
|
namespace = self.datavars_module
|
|
|
|
namespace = self.datavars_module
|
|
|
|
|
|
|
|
|
|
|
@ -2251,7 +2255,7 @@ class DirectoryProcessor:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
namespace['current_template'] = ""
|
|
|
|
namespace['current_template'] = ""
|
|
|
|
|
|
|
|
|
|
|
|
def process_template_directories(self) -> NoReturn:
|
|
|
|
def process_template_directories(self) -> None:
|
|
|
|
'''Метод для обхода шаблонов, содержащихся в каталогах из
|
|
|
|
'''Метод для обхода шаблонов, содержащихся в каталогах из
|
|
|
|
main.cl_template.path.'''
|
|
|
|
main.cl_template.path.'''
|
|
|
|
# Режим заполнения очередей директорий пакетов, необходимых для более
|
|
|
|
# Режим заполнения очередей директорий пакетов, необходимых для более
|
|
|
@ -2319,12 +2323,11 @@ class DirectoryProcessor:
|
|
|
|
PackageCreator.save_all()
|
|
|
|
PackageCreator.save_all()
|
|
|
|
return self.template_executor.changed_files
|
|
|
|
return self.template_executor.changed_files
|
|
|
|
|
|
|
|
|
|
|
|
def _run_template_from_base_directory(
|
|
|
|
def _run_template_from_base_directory(self, template_names: List[str],
|
|
|
|
self, template_names: List[str],
|
|
|
|
base_directory: str,
|
|
|
|
base_directory: str,
|
|
|
|
package: Optional[Package] = None,
|
|
|
|
package: Optional[Package] = None,
|
|
|
|
directory_tree: Optional[dict] = None
|
|
|
|
directory_tree: Optional[dict] = None
|
|
|
|
) -> None:
|
|
|
|
) -> NoReturn:
|
|
|
|
|
|
|
|
'''Метод для запуска шаблонов файлов находящихся в базовой директории.
|
|
|
|
'''Метод для запуска шаблонов файлов находящихся в базовой директории.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
self.template_engine.change_directory(base_directory)
|
|
|
|
self.template_engine.change_directory(base_directory)
|
|
|
@ -2380,6 +2383,7 @@ class DirectoryProcessor:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
template_package = package
|
|
|
|
template_package = package
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Дефолтные значения разные для упрощения написания шаблонов.
|
|
|
|
if not parameters.run and not parameters.exec:
|
|
|
|
if not parameters.run and not parameters.exec:
|
|
|
|
if not parameters.format:
|
|
|
|
if not parameters.format:
|
|
|
|
parameters.set_parameter({'format': 'raw'})
|
|
|
|
parameters.set_parameter({'format': 'raw'})
|
|
|
@ -2396,7 +2400,7 @@ class DirectoryProcessor:
|
|
|
|
template_text=template_text,
|
|
|
|
template_text=template_text,
|
|
|
|
package=template_package)
|
|
|
|
package=template_package)
|
|
|
|
|
|
|
|
|
|
|
|
def _execute_handlers(self) -> NoReturn:
|
|
|
|
def _execute_handlers(self) -> None:
|
|
|
|
'''Метод для запуска обработчиков добавленных в очередь обработчиков
|
|
|
|
'''Метод для запуска обработчиков добавленных в очередь обработчиков
|
|
|
|
с помощью параметра notify.'''
|
|
|
|
с помощью параметра notify.'''
|
|
|
|
self.output.set_info('Processing handlers...')
|
|
|
|
self.output.set_info('Processing handlers...')
|
|
|
@ -2462,7 +2466,7 @@ class DirectoryProcessor:
|
|
|
|
FILE, handler_path,
|
|
|
|
FILE, handler_path,
|
|
|
|
template_text=handler_text)
|
|
|
|
template_text=handler_text)
|
|
|
|
|
|
|
|
|
|
|
|
def _merge_packages(self) -> NoReturn:
|
|
|
|
def _merge_packages(self) -> None:
|
|
|
|
'''Метод для выполнения шаблонов относящихся к пакетам, указанным во
|
|
|
|
'''Метод для выполнения шаблонов относящихся к пакетам, указанным во
|
|
|
|
всех встреченных значениях параметра merge.'''
|
|
|
|
всех встреченных значениях параметра merge.'''
|
|
|
|
not_merged_packages = []
|
|
|
|
not_merged_packages = []
|
|
|
@ -2527,7 +2531,7 @@ class DirectoryProcessor:
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.output.set_success('All packages are merged.')
|
|
|
|
self.output.set_success('All packages are merged.')
|
|
|
|
|
|
|
|
|
|
|
|
def _run_exec_files(self) -> NoReturn:
|
|
|
|
def _run_exec_files(self) -> None:
|
|
|
|
'''Метод для выполнения скриптов, полученных в результате обработки
|
|
|
|
'''Метод для выполнения скриптов, полученных в результате обработки
|
|
|
|
шаблонов с параметром exec.'''
|
|
|
|
шаблонов с параметром exec.'''
|
|
|
|
for exec_file_path, exec_info in\
|
|
|
|
for exec_file_path, exec_info in\
|
|
|
@ -2554,7 +2558,7 @@ class DirectoryProcessor:
|
|
|
|
current_target_path: str,
|
|
|
|
current_target_path: str,
|
|
|
|
directory_parameters: ParametersContainer,
|
|
|
|
directory_parameters: ParametersContainer,
|
|
|
|
directory_tree: Union[dict, DirectoryTree] = {},
|
|
|
|
directory_tree: Union[dict, DirectoryTree] = {},
|
|
|
|
package: Optional[Package] = None) -> NoReturn:
|
|
|
|
package: Optional[Package] = None) -> None:
|
|
|
|
'''Метод для рекурсивного обхода директорий с шаблонами, а также, при
|
|
|
|
'''Метод для рекурсивного обхода директорий с шаблонами, а также, при
|
|
|
|
необходимости, заполнения деревьев директорий шаблонов, с помощью
|
|
|
|
необходимости, заполнения деревьев директорий шаблонов, с помощью
|
|
|
|
которых далее выполняются шаблоны пакетов из merge.'''
|
|
|
|
которых далее выполняются шаблоны пакетов из merge.'''
|
|
|
@ -2805,7 +2809,6 @@ class DirectoryProcessor:
|
|
|
|
|
|
|
|
|
|
|
|
if self.fill_trees:
|
|
|
|
if self.fill_trees:
|
|
|
|
directory_tree = {}
|
|
|
|
directory_tree = {}
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _scan_directory(self, directory_path: str
|
|
|
|
def _scan_directory(self, directory_path: str
|
|
|
|
) -> Tuple[List[str], List[str]]:
|
|
|
|
) -> Tuple[List[str], List[str]]:
|
|
|
|