ensure file integrity for tex formatters
This commit is contained in:
parent
785eb6923f
commit
f8a6f83de9
9 changed files with 65 additions and 13 deletions
|
@ -1,11 +1,9 @@
|
||||||
from .build_information import BuildInfo
|
from .build_information import BuildInfo
|
||||||
from .pytex_file import TexFileToFormat
|
from .pytex_file import TexFileToFormat
|
||||||
from .pytex_msg import pytex_msg
|
from .pytex_msg import pytex_msg
|
||||||
from .checksum import md5
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'BuildInfo',
|
'BuildInfo',
|
||||||
'TexFileToFormat',
|
'TexFileToFormat',
|
||||||
'pytex_msg',
|
'pytex_msg'
|
||||||
'md5'
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,7 +5,7 @@ from PyTeX.build.git_hook import is_recent, get_latest_commit
|
||||||
from PyTeX import PackageFormatter, ClassFormatter, DictionaryFormatter
|
from PyTeX import PackageFormatter, ClassFormatter, DictionaryFormatter
|
||||||
from PyTeX.errors import *
|
from PyTeX.errors import *
|
||||||
from .pytex_msg import pytex_msg
|
from .pytex_msg import pytex_msg
|
||||||
from .checksum import md5
|
from PyTeX.utils import md5
|
||||||
|
|
||||||
from .build_information import BuildInfo
|
from .build_information import BuildInfo
|
||||||
|
|
||||||
|
@ -129,7 +129,11 @@ class TexFileToFormat:
|
||||||
else:
|
else:
|
||||||
raise ProgrammingError
|
raise ProgrammingError
|
||||||
formatter.make_default_macros()
|
formatter.make_default_macros()
|
||||||
written_files = formatter.format_file(self.src_path, self.build_path)
|
written_files = formatter.format_file(
|
||||||
|
input_path=self.src_path,
|
||||||
|
output_dir=self.build_path,
|
||||||
|
relative_name=str(self.src_path.relative_to(self.src_root)),
|
||||||
|
last_build_info=self.last_build_info_all)
|
||||||
build_infos = []
|
build_infos = []
|
||||||
for written_file in written_files:
|
for written_file in written_files:
|
||||||
info = {
|
info = {
|
||||||
|
|
|
@ -29,7 +29,13 @@ class DictionaryFormatter(Formatter):
|
||||||
def expected_file_name(self):
|
def expected_file_name(self):
|
||||||
return self.file_name
|
return self.file_name
|
||||||
|
|
||||||
def format_file(self, input_path: Path, output_dir: Path = None) -> List[str]:
|
def format_file(
|
||||||
|
self,
|
||||||
|
input_path: Path,
|
||||||
|
output_dir: Path = None,
|
||||||
|
relative_name: Optional[str] = None,
|
||||||
|
last_build_info: Optional[List[Dict]] = None
|
||||||
|
) -> List[str]:
|
||||||
self.source_file_name = str(input_path.name)
|
self.source_file_name = str(input_path.name)
|
||||||
written_files = []
|
written_files = []
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from .errors import PyTexError, SubmoduleDirtyForbiddenError, ProgrammingError, ExtraHeaderFileNotFoundError, \
|
from .errors import PyTexError, SubmoduleDirtyForbiddenError, ProgrammingError, ExtraHeaderFileNotFoundError, \
|
||||||
UnknownTexVersionError
|
UnknownTexVersionError, ModifiedFileInBuildDirectoryError, UnknownFileInBuildDirectoryError
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'PyTexError',
|
'PyTexError',
|
||||||
'SubmoduleDirtyForbiddenError',
|
'SubmoduleDirtyForbiddenError',
|
||||||
'ProgrammingError',
|
'ProgrammingError',
|
||||||
'ExtraHeaderFileNotFoundError',
|
'ExtraHeaderFileNotFoundError',
|
||||||
'UnknownTexVersionError'
|
'UnknownTexVersionError',
|
||||||
|
'ModifiedFileInBuildDirectoryError',
|
||||||
|
'UnknownFileInBuildDirectoryError'
|
||||||
]
|
]
|
||||||
|
|
|
@ -33,3 +33,24 @@ class UnknownTexVersionError(PyTexError):
|
||||||
f"Unknown TeX version {tex_version}given. Only 'LaTeX2e' and 'LaTeX3' "
|
f"Unknown TeX version {tex_version}given. Only 'LaTeX2e' and 'LaTeX3' "
|
||||||
f"are currently supported"
|
f"are currently supported"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ModifiedFileInBuildDirectoryError(PyTexError):
|
||||||
|
def __init__(self, filename: str):
|
||||||
|
super().__init__(
|
||||||
|
f"File '{filename}' in the build directory has been modified since the last build. "
|
||||||
|
f"Refusing to overwrite a modified file, since you could lose your manual changes. "
|
||||||
|
f"If you are sure you do not need this anymore, delete it manually and build again. "
|
||||||
|
f"Note that for exactly this reason, it is strongly discouraged to edit built files directly."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownFileInBuildDirectoryError(PyTexError):
|
||||||
|
def __init__(self, filename: str):
|
||||||
|
super().__init__(
|
||||||
|
f"Unknown file {filename} in build directory found. "
|
||||||
|
f"PyTeX has no knowledge whether this file has been built by PyTeX. "
|
||||||
|
f"Refusing to overwrite this file, since you could lose your data. "
|
||||||
|
f"If you are sure, this can be got rid of, delete the file manually, "
|
||||||
|
f"and run the build again."
|
||||||
|
)
|
|
@ -1,5 +1,5 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List, Dict, Optional
|
||||||
|
|
||||||
|
|
||||||
class Formatter:
|
class Formatter:
|
||||||
|
@ -10,7 +10,7 @@ class Formatter:
|
||||||
def make_default_macros(self) -> None:
|
def make_default_macros(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def format_file(self, input_path: Path, output_dir: Path) -> List[str]:
|
def format_file(self, input_path: Path, output_dir: Path, last_build_info: Optional[List[Dict]] = None) -> List[str]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def expected_file_name(self) -> str:
|
def expected_file_name(self) -> str:
|
||||||
|
|
|
@ -5,7 +5,8 @@ from typing import Dict, Optional, List
|
||||||
from datetime import *
|
from datetime import *
|
||||||
|
|
||||||
from PyTeX.base import Attributes, Args
|
from PyTeX.base import Attributes, Args
|
||||||
from PyTeX.errors import UnknownTexVersionError
|
from PyTeX.errors import *
|
||||||
|
from PyTeX.utils import md5
|
||||||
|
|
||||||
from .formatter import Formatter
|
from .formatter import Formatter
|
||||||
|
|
||||||
|
@ -112,7 +113,12 @@ class TexFormatter(Formatter):
|
||||||
'format_kwargs': kwargs
|
'format_kwargs': kwargs
|
||||||
}
|
}
|
||||||
|
|
||||||
def format_file(self, input_path: Path, output_dir: Path = None) -> List[str]:
|
def format_file(
|
||||||
|
self,
|
||||||
|
input_path: Path,
|
||||||
|
output_dir: Path = None,
|
||||||
|
relative_name: Optional[str] = None,
|
||||||
|
last_build_info: Optional[List[Dict]] = None) -> List[str]:
|
||||||
self.source_file_name = str(input_path.name)
|
self.source_file_name = str(input_path.name)
|
||||||
input_file = input_path.open()
|
input_file = input_path.open()
|
||||||
lines = input_file.readlines()
|
lines = input_file.readlines()
|
||||||
|
@ -127,5 +133,15 @@ class TexFormatter(Formatter):
|
||||||
if output_dir is None:
|
if output_dir is None:
|
||||||
output_dir = input_path.parent
|
output_dir = input_path.parent
|
||||||
output_dir.mkdir(parents=True, exist_ok=True)
|
output_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
if (output_dir / self.file_name).exists():
|
||||||
|
found = False
|
||||||
|
for info in last_build_info:
|
||||||
|
if info['source file'] == relative_name:
|
||||||
|
if not md5(output_dir / self.file_name) == info['md5sum']:
|
||||||
|
raise ModifiedFileInBuildDirectoryError(str(output_dir / self.file_name))
|
||||||
|
found = True
|
||||||
|
if not found:
|
||||||
|
raise UnknownFileInBuildDirectoryError(str(output_dir / self.file_name))
|
||||||
|
|
||||||
(output_dir / self.file_name).write_text(''.join(newlines))
|
(output_dir / self.file_name).write_text(''.join(newlines))
|
||||||
return [str(self.file_name)]
|
return [str(self.file_name)]
|
||||||
|
|
5
utils/__init__.py
Normal file
5
utils/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from. checksum import md5
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
'md5'
|
||||||
|
]
|
Loading…
Reference in a new issue