ensure file integrity for tex formatters

This commit is contained in:
Maximilian Keßler 2022-01-13 20:04:18 +01:00
parent 785eb6923f
commit f8a6f83de9
9 changed files with 65 additions and 13 deletions

View file

@ -1,11 +1,9 @@
from .build_information import BuildInfo
from .pytex_file import TexFileToFormat
from .pytex_msg import pytex_msg
from .checksum import md5
__all__ = [
'BuildInfo',
'TexFileToFormat',
'pytex_msg',
'md5'
'pytex_msg'
]

View file

@ -5,7 +5,7 @@ from PyTeX.build.git_hook import is_recent, get_latest_commit
from PyTeX import PackageFormatter, ClassFormatter, DictionaryFormatter
from PyTeX.errors import *
from .pytex_msg import pytex_msg
from .checksum import md5
from PyTeX.utils import md5
from .build_information import BuildInfo
@ -129,7 +129,11 @@ class TexFileToFormat:
else:
raise ProgrammingError
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 = []
for written_file in written_files:
info = {

View file

@ -29,9 +29,15 @@ class DictionaryFormatter(Formatter):
def expected_file_name(self):
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)
written_files = []
written_files = []
if self.header:
lines = '%' * 80 + '\n' \

View file

@ -1,10 +1,12 @@
from .errors import PyTexError, SubmoduleDirtyForbiddenError, ProgrammingError, ExtraHeaderFileNotFoundError, \
UnknownTexVersionError
UnknownTexVersionError, ModifiedFileInBuildDirectoryError, UnknownFileInBuildDirectoryError
__all__ = [
'PyTexError',
'SubmoduleDirtyForbiddenError',
'ProgrammingError',
'ExtraHeaderFileNotFoundError',
'UnknownTexVersionError'
'UnknownTexVersionError',
'ModifiedFileInBuildDirectoryError',
'UnknownFileInBuildDirectoryError'
]

View file

@ -33,3 +33,24 @@ class UnknownTexVersionError(PyTexError):
f"Unknown TeX version {tex_version}given. Only 'LaTeX2e' and 'LaTeX3' "
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."
)

View file

@ -1,5 +1,5 @@
from pathlib import Path
from typing import List
from typing import List, Dict, Optional
class Formatter:
@ -10,7 +10,7 @@ class Formatter:
def make_default_macros(self) -> None:
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
def expected_file_name(self) -> str:

View file

@ -5,7 +5,8 @@ from typing import Dict, Optional, List
from datetime import *
from PyTeX.base import Attributes, Args
from PyTeX.errors import UnknownTexVersionError
from PyTeX.errors import *
from PyTeX.utils import md5
from .formatter import Formatter
@ -112,7 +113,12 @@ class TexFormatter(Formatter):
'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)
input_file = input_path.open()
lines = input_file.readlines()
@ -127,5 +133,15 @@ class TexFormatter(Formatter):
if output_dir is None:
output_dir = input_path.parent
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))
return [str(self.file_name)]

5
utils/__init__.py Normal file
View file

@ -0,0 +1,5 @@
from. checksum import md5
__all__ = [
'md5'
]