set up version info after build

This commit is contained in:
Maximilian Keßler 2022-02-09 01:22:25 +01:00
parent 1bcd6040fb
commit 410bf3d519
3 changed files with 64 additions and 19 deletions

View file

@ -1,9 +1,11 @@
import json
from pathlib import Path from pathlib import Path
from typing import Optional, Union, List, Tuple, Set from typing import Optional, Union, List, Tuple, Set
import shutil import shutil
from .enums import PyTeXRootDirType from .enums import PyTeXRootDirType
from .pytex_config import PyTeXConfig from .pytex_config import PyTeXConfig
from ...format.formatting_config import FormattingConfig
from ...logger import logger from ...logger import logger
from .constants import * from .constants import *
from ..versioning.version_info.version_info import VersionInfo, FileVersionInfo from ..versioning.version_info.version_info import VersionInfo, FileVersionInfo
@ -35,6 +37,7 @@ class PyTeXBuilder:
# Non-public attributes # Non-public attributes
self._build_target_type: Optional[PyTeXRootDirType] = None self._build_target_type: Optional[PyTeXRootDirType] = None
self._old_version_info: Optional[VersionInfo] = None self._old_version_info: Optional[VersionInfo] = None
self._new_version_info: VersionInfo = VersionInfo()
self._output_files: List[PyTeXOutputFile] = [] self._output_files: List[PyTeXOutputFile] = []
self._pytex_files: List[PyTeXSourceFile] = [] self._pytex_files: List[PyTeXSourceFile] = []
self._files_to_clean: Set[RelativePath] = set() self._files_to_clean: Set[RelativePath] = set()
@ -42,6 +45,10 @@ class PyTeXBuilder:
self._files_to_build: Set[PyTeXSourceFile] = set() self._files_to_build: Set[PyTeXSourceFile] = set()
self._tmp_dir: Path = self._root_dir / '.pytex' self._tmp_dir: Path = self._root_dir / '.pytex'
@classmethod
def is_ignored_in_build_dir(cls, path: RelativePath):
return path.relative_path.name == VERSION_INFO_FILE
def build_tex_sources(self) -> bool: def build_tex_sources(self) -> bool:
self._build_target_type = PyTeXRootDirType.TEX_SOURCE self._build_target_type = PyTeXRootDirType.TEX_SOURCE
return self._build() return self._build()
@ -179,10 +186,11 @@ class PyTeXBuilder:
for file in self.target_root.rglob('*') for file in self.target_root.rglob('*')
] ]
for file in out_dir_files: for file in out_dir_files:
if not file.relative_path.is_dir(): if not file.is_dir():
version = self._old_version_lookup(file) version = self._old_version_lookup(file)
if version.file_hash != md5(file.path): if version.file_hash != md5(file.path):
if self.pytex_config.clean_old_files: if self.pytex_config.clean_old_files:
if not self.is_ignored_in_build_dir(file):
raise NotImplementedError # Not ok raise NotImplementedError # Not ok
else: else:
if self.pytex_config.overwrite_existing_files: if self.pytex_config.overwrite_existing_files:
@ -193,10 +201,13 @@ class PyTeXBuilder:
raise NotImplementedError raise NotImplementedError
# Not ok iff we are going to write this file # Not ok iff we are going to write this file
def _dependencies_hash(self, pytex_output_file: PyTeXOutputFile) -> str: def _dependencies_hash(self, file: Union[PyTeXOutputFile, PyTeXSourceFile]) -> str:
t = pytex_output_file.dependencies if isinstance(file, PyTeXOutputFile):
deps: Set[str] = set(t) deps: Set[str] = set(file.dependencies)
deps.add(pytex_output_file.source_file.relative_path.path.name) deps.add(file.source_file.relative_path.path.name)
else:
deps = set(file.formatter.dependencies)
deps.add(file.relative_path.path.name)
hashes = set() hashes = set()
for dep in deps: for dep in deps:
hashes.add( hashes.add(
@ -207,26 +218,44 @@ class PyTeXBuilder:
def _init_output_files(self): def _init_output_files(self):
for source_file in self._pytex_files: for source_file in self._pytex_files:
for output_file in source_file.output_files: for output_file in source_file.output_files:
self._output_files.append( h = output_file.with_root(self.target_root)
PyTeXOutputFile( f = PyTeXOutputFile(
output_file=output_file, output_file=h,
source_file=source_file, source_file=source_file,
last_version_info=self._old_version_lookup(output_file) last_version_info=self._old_version_lookup(output_file)
) )
self._output_files.append(
f
) )
def _compute_files_to_build(self): def _compute_files_to_build(self):
self._files_to_build = { self._new_version_info.files = []
output_file.source_file for output_file in self._output_files for output_file in self._output_files:
if self._dependencies_hash(output_file) != output_file.last_version_info.sources_hash if self._dependencies_hash(output_file) != output_file.last_version_info.sources_hash \
or output_file.last_version_info.file_hash != output_file.file_hash or output_file.last_version_info.file_hash != output_file.file_hash:
} self._files_to_build.add(output_file.source_file)
else:
self._new_version_info.files.append(output_file.last_version_info) # File will not change
# TODO actually, this is not totally correct
def _build_files(self): def _build_files(self):
for source_file in self._files_to_build: for source_file in self._files_to_build:
out_dir = self._tmp_dir / source_file.file_hash out_dir = self._tmp_dir / source_file.file_hash
out_dir.mkdir(exist_ok=False, parents=True) out_dir.mkdir(exist_ok=False, parents=True)
new_config: List[Tuple[RelativePath, FormattingConfig]] = \
source_file.format(self._tmp_dir / source_file.file_hash) source_file.format(self._tmp_dir / source_file.file_hash)
for output_file in source_file.output_files:
# TODO: handle this new config file
# TODO: handle git stuff / meta info stuff
file_version_info = FileVersionInfo()
file_version_info.relative_name = str(output_file.relative_path)
file_version_info.file_hash = str(md5(
self._tmp_dir / source_file.file_hash / output_file.relative_path.name
))
file_version_info.sources_hash = self._dependencies_hash(source_file)
self._new_version_info.files.append(
file_version_info
)
def _move_files(self): def _move_files(self):
for source_file in self._files_to_build: for source_file in self._files_to_build:
@ -238,8 +267,12 @@ class PyTeXBuilder:
tmp_dir / filename.relative_path.name, tmp_dir / filename.relative_path.name,
out_dir / filename.relative_path.name out_dir / filename.relative_path.name
) )
if self._tmp_dir.exists():
shutil.rmtree(self._tmp_dir) shutil.rmtree(self._tmp_dir)
def _write_version_info(self):
self._new_version_info.dump_as_json(self.target_root / VERSION_INFO_FILE)
def _build(self) -> bool: def _build(self) -> bool:
logger.info("Starting build") logger.info("Starting build")
self._load_pytex_files() self._load_pytex_files()
@ -247,9 +280,13 @@ class PyTeXBuilder:
self._init_output_files() self._init_output_files()
logger.info(f"Found {len(self._output_files)} potential files to build.") logger.info(f"Found {len(self._output_files)} potential files to build.")
self._compute_files_to_build() self._compute_files_to_build()
if len(self._files_to_build) == 0:
logger.info(f"Everything up to date, nothing to build!")
return True
logger.info(f"Needing to build {len(self._files_to_build)} many files.") logger.info(f"Needing to build {len(self._files_to_build)} many files.")
self._check_output_directory_integrity() self._check_output_directory_integrity()
logger.info(f"Starting build") logger.info(f"Starting build")
self._build_files() self._build_files()
self._move_files() self._move_files()
self._write_version_info()
return True return True

View file

@ -1,3 +1,4 @@
from ctypes import Union
from pathlib import Path from pathlib import Path
from PyTeX.build.build.enums import PyTeXRootDirType from PyTeX.build.build.enums import PyTeXRootDirType
@ -14,6 +15,7 @@ class RelativePath:
*args, *args,
**kwargs **kwargs
): ):
pass
self._path = Path(*args, **kwargs) self._path = Path(*args, **kwargs)
self._root_dir = root_dir self._root_dir = root_dir
@ -59,3 +61,9 @@ class RelativePath:
return self.relative_to(self._root_dir) return self.relative_to(self._root_dir)
except ValueError as e: except ValueError as e:
raise NotImplementedError raise NotImplementedError
def with_root(self, root: Path):
return RelativePath(
root,
root / self.relative_path
)

View file

@ -79,7 +79,7 @@ class Config:
else: else:
simple_dict = self.to_json() simple_dict = self.to_json()
if simple_dict is not None: if simple_dict is not None:
json.dump(simple_dict, config) json.dump(simple_dict, config, indent=4)
else: else:
pass # TODO pass # TODO