6
0
Derivar 0
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

96 linhas
3.7 KiB

Este ficheiro contém caracteres Unicode ambíguos!

Este ficheiro contém caracteres Unicode ambíguos que podem ser confundidos com outros da sua configuração regional vigente. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para realçar esses caracteres.

# vim: fileencoding=utf-8
#
from .base_format import Format
from calculate.utils.files import Process
from calculate.templates.format.base_format import FormatError
from ..template_engine import ParametersContainer, Variables
from ...variables.datavars import NamespaceNode
from ...variables.loader import Datavars
from typing import Union
from os import path
class PatchFormat(Format):
FORMAT = 'patch'
EXECUTABLE = True
def __init__(self, patch_text: str,
template_path: str,
parameters: ParametersContainer,
datavars: Union[Datavars, NamespaceNode, Variables]):
self._patch_text = patch_text
self._cwd_path = '/'
self._last_level = 0
# Измененные файлы.
self.changed_files = dict()
# Предупреждения.
self._warnings: list = []
def execute_format(self, target_path, chroot_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', executable=True)
if self._patch_text:
self._patch_document()
return self.changed_files
else:
raise FormatError('empty patch file', executable=True)
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', executable=True)
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:
'C'})
else:
self.changed_files.update({changed_file_path:
'D'})
return patch_run.read()
else:
return ''
def __bool__(self):
return bool(self._patch_text)
@property
def warnings(self):
return self._warnings