From f8756037cb2280b006125bd7d5e44ed210c5f205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Ke=C3=9Fler?= Date: Mon, 18 Oct 2021 16:27:20 +0200 Subject: [PATCH] incremental building: skip packages that were not modified and are already built --- build.py | 11 +++++++-- build_scripts/build/build.py | 39 ++++++++++++++++++++++++++---- build_scripts/git_hook/__init__.py | 4 ++- build_scripts/git_hook/recent.py | 14 +++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 build_scripts/git_hook/recent.py diff --git a/build.py b/build.py index 538ead2..256263a 100644 --- a/build.py +++ b/build.py @@ -1,8 +1,15 @@ -from build_scripts.build import build +import sys from pathlib import Path +from build_scripts.build import build + if __name__ == "__main__": + check_existence = True + if len(sys.argv) == 2: + if sys.argv[1] == '--only-new': + check_existence = False build( src_dir=Path('./src').resolve(), - build_dir=Path('./build').resolve() + build_dir=Path('./build').resolve(), + check_existence=check_existence ) diff --git a/build_scripts/build/build.py b/build_scripts/build/build.py index cb4ea8d..812a3c3 100644 --- a/build_scripts/build/build.py +++ b/build_scripts/build/build.py @@ -3,12 +3,12 @@ import git import PyTeX -from build_scripts.git_hook.git_version import get_latest_commit +from build_scripts.git_hook import get_latest_commit, is_recent from .build_information import build_information -def build(src_dir: Path, build_dir: Path): +def build(src_dir: Path, build_dir: Path, check_existence: bool = True): print('[PyTeX] Getting git repository information...') extra_header, repo_description = build_information() print('[PyTeX] Building version {version} of LatexPackages'.format(version=repo_description)) @@ -17,22 +17,51 @@ def build(src_dir: Path, build_dir: Path): extra_header += ['WARNING: Local changes to git repository detected.', ' The build will not be reproducible (!)'] num_packages = 0 + num_skipped_packages = 0 num_classes = 0 + num_skipped_classes = 0 for file in src_dir.rglob('*.pysty'): + output_dir = build_dir / str(file.parent.relative_to(src_dir)) + if not is_recent(file, git.Repo()): + if not check_existence: + print('[PyTex] Skipping file {file} since it was not modified since last build'.format(file=file.name)) + num_skipped_packages += 1 + continue + else: + if (output_dir / ('mkessler-' + str(file.with_suffix('.sty').name))).exists(): + print('[PyTex] Skipping file {file} since it was not modified since ' + 'last build and already exists'.format(file=file.name)) + num_skipped_packages += 1 + continue + num_packages += 1 formatter = PyTeX.PackageFormatter( package_name=file.with_suffix('').name, extra_header=extra_header) print('[PyTeX] Writing file {}'.format(formatter.file_name)) formatter.make_default_macros() - formatter.format_file(file, build_dir / str(file.parent.relative_to(src_dir))) + formatter.format_file(file, output_dir) for file in src_dir.rglob('*.pycls'): + output_dir = build_dir / str(file.parent.relative_to(src_dir)) + if not is_recent(file, git.Repo()): + if not check_existence: + print('[PyTex] Skipping file {file} since it was not modified since last build'.format(file=file.name)) + num_skipped_classes += 1 + continue + else: + if (output_dir / ('mkessler-' + str(file.with_suffix('.cls').name))).exists(): + print('[PyTex] Skipping file {file} since it was not modified since ' + 'last build and already exists'.format(file=file.name)) + num_skipped_classes += 1 + continue + output_dir = build_dir / str(file.parent.relative_to(src_dir)) num_classes += 1 formatter = PyTeX.ClassFormatter( class_name=file.with_suffix('').name, extra_header=extra_header) print('[PyTeX] Writing class file {}'.format(formatter.file_name)) formatter.make_default_macros() - formatter.format_file(file, build_dir / str(file.parent.relative_to(src_dir))) - print(f'[PyTeX] Successfully built {num_packages} packages and {num_classes} classes in {build_dir}/') + formatter.format_file(input_path=file, output_dir=output_dir) + print(f'[PyTeX] Successfully built {num_packages} packages (skipped {num_skipped_packages}) ' + f'and {num_classes} classes (skipped {num_skipped_classes}) in {build_dir}/') diff --git a/build_scripts/git_hook/__init__.py b/build_scripts/git_hook/__init__.py index 422c72e..851f2bc 100644 --- a/build_scripts/git_hook/__init__.py +++ b/build_scripts/git_hook/__init__.py @@ -1,7 +1,9 @@ from .git_version import git_describe, get_history, get_latest_commit +from .recent import is_recent __all__ = [ 'git_describe', 'get_history', - 'get_latest_commit' + 'get_latest_commit', + 'is_recent' ] diff --git a/build_scripts/git_hook/recent.py b/build_scripts/git_hook/recent.py new file mode 100644 index 0000000..acc7480 --- /dev/null +++ b/build_scripts/git_hook/recent.py @@ -0,0 +1,14 @@ +from .git_version import get_latest_commit + + +def is_recent(file, repo): + modified_files = [item.a_path for item in repo.index.diff(None)] + if file in modified_files: + return True + + for parent in get_latest_commit(repo).parents: + newly_committed_files = [item.a_path for item in repo.index.diff(parent)] + if file in newly_committed_files: + return True + return False +