|
|
|
@ -7,6 +7,7 @@ from collections import OrderedDict
|
|
|
|
|
from .files import read_file, read_link, join_paths, FilesError
|
|
|
|
|
from typing import (
|
|
|
|
|
Generator,
|
|
|
|
|
Tuple,
|
|
|
|
|
Union,
|
|
|
|
|
List,
|
|
|
|
|
Any
|
|
|
|
@ -293,6 +294,67 @@ class Version:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ContentsParser(metaclass=Singleton):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._parsers = {'dir': ContentsParser._parse_dir,
|
|
|
|
|
'sym': ContentsParser._parse_sym,
|
|
|
|
|
'obj': ContentsParser._parse_obj}
|
|
|
|
|
|
|
|
|
|
self._patterns = {'dir': "dir {path}",
|
|
|
|
|
'sym': "sym {path} -> {target} {mtime}",
|
|
|
|
|
'obj': "obj {path} {md5} {mtime}"}
|
|
|
|
|
|
|
|
|
|
def parse(self, text: str) -> OrderedDict:
|
|
|
|
|
output = OrderedDict()
|
|
|
|
|
for line in text.split('\n'):
|
|
|
|
|
line = line.strip()
|
|
|
|
|
if not line:
|
|
|
|
|
continue
|
|
|
|
|
parts = line.split()
|
|
|
|
|
path, value = self._parsers[parts[0]](parts)
|
|
|
|
|
output[path] = value
|
|
|
|
|
return output
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _parse_dir(parts: List[str]) -> Tuple[str, dict]:
|
|
|
|
|
try:
|
|
|
|
|
return parts[1], {'type': 'dir'}
|
|
|
|
|
except Exception as error:
|
|
|
|
|
print(str(error))
|
|
|
|
|
print("parts:", parts)
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _parse_obj(parts: List[str]) -> Tuple[str, dict]:
|
|
|
|
|
try:
|
|
|
|
|
return parts[1], {'type': 'obj',
|
|
|
|
|
'md5': parts[2].strip(),
|
|
|
|
|
'mtime': parts[3].strip()}
|
|
|
|
|
except Exception as error:
|
|
|
|
|
print(str(error))
|
|
|
|
|
print("parts:", parts)
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _parse_sym(parts: List[str]) -> Tuple[str, dict]:
|
|
|
|
|
try:
|
|
|
|
|
return parts[1], {'type': 'sym',
|
|
|
|
|
'target': parts[3].strip(),
|
|
|
|
|
'mtime': parts[4].strip()}
|
|
|
|
|
except Exception as error:
|
|
|
|
|
print(str(error))
|
|
|
|
|
print("parts:", parts)
|
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
def render(self, contents_dictionary: OrderedDict) -> str:
|
|
|
|
|
lines = []
|
|
|
|
|
for path, value in contents_dictionary.items():
|
|
|
|
|
lines.append(
|
|
|
|
|
self._patterns[value['type']].format(path=path, **value))
|
|
|
|
|
lines.append('')
|
|
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class OldContentsParser(metaclass=Singleton):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
'''Метод для инициализации парсеров.'''
|
|
|
|
|
sym_keyword = Literal('sym')
|
|
|
|
|