Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

96 righe
3.7 KiB

Questo file contiene caratteri Unicode ambigui!

Questo file contiene caratteri Unicode ambigui che possono essere confusi con altri nella tua localizzazione attuale. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per evidenziare questi caratteri.

# 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