diff --git a/build/utils/__init__.py b/build/utils/__init__.py index 52a55f1..a29fb42 100644 --- a/build/utils/__init__.py +++ b/build/utils/__init__.py @@ -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' ] diff --git a/build/utils/pytex_file.py b/build/utils/pytex_file.py index a82d132..ab9c9b9 100644 --- a/build/utils/pytex_file.py +++ b/build/utils/pytex_file.py @@ -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 = { diff --git a/default_formatters/dictionary_formatter.py b/default_formatters/dictionary_formatter.py index 1bc5553..ff4075b 100644 --- a/default_formatters/dictionary_formatter.py +++ b/default_formatters/dictionary_formatter.py @@ -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' \ diff --git a/errors/__init__.py b/errors/__init__.py index 0aa8c91..3377080 100644 --- a/errors/__init__.py +++ b/errors/__init__.py @@ -1,10 +1,12 @@ from .errors import PyTexError, SubmoduleDirtyForbiddenError, ProgrammingError, ExtraHeaderFileNotFoundError, \ - UnknownTexVersionError + UnknownTexVersionError, ModifiedFileInBuildDirectoryError, UnknownFileInBuildDirectoryError __all__ = [ 'PyTexError', 'SubmoduleDirtyForbiddenError', 'ProgrammingError', 'ExtraHeaderFileNotFoundError', - 'UnknownTexVersionError' + 'UnknownTexVersionError', + 'ModifiedFileInBuildDirectoryError', + 'UnknownFileInBuildDirectoryError' ] diff --git a/errors/errors.py b/errors/errors.py index 911ba89..f1cbb9c 100644 --- a/errors/errors.py +++ b/errors/errors.py @@ -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." + ) \ No newline at end of file diff --git a/formatter/formatter.py b/formatter/formatter.py index 7708731..d3a95f8 100644 --- a/formatter/formatter.py +++ b/formatter/formatter.py @@ -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: diff --git a/formatter/tex_formatter.py b/formatter/tex_formatter.py index 39bfd98..d854668 100644 --- a/formatter/tex_formatter.py +++ b/formatter/tex_formatter.py @@ -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)] diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..5e98821 --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1,5 @@ +from. checksum import md5 + +__all__ = [ + 'md5' +] diff --git a/build/utils/checksum.py b/utils/checksum.py similarity index 100% rename from build/utils/checksum.py rename to utils/checksum.py