feature: create zip, fixes #9

This commit is contained in:
Matthias Jung
2026-02-22 23:49:45 +01:00
parent 0ffd0a3c24
commit 3596ce80d4
2 changed files with 43 additions and 0 deletions
+5
View File
@@ -23,6 +23,7 @@ def main(
output: Annotated[str | None, typer.Option("--output", "-o", help="Destination directory to build to.")] = None,
render_editions: Annotated[bool, typer.Option(help="Skip building editions.")] = True,
render_solutions: Annotated[bool, typer.Option(help="Skip building solutions.")] = True,
build_zip: Annotated[bool, typer.Option(help="Whether to build a zip file of the output.")] = False,
) -> None:
conf = config.Config(content_path=input, build_path=output)
bd = build.Build(conf)
@@ -42,6 +43,10 @@ def main(
# Copy assets to build folder
bd.build_assets()
if build_zip:
# Build zip file of output
bd.build_zip()
if __name__ == "__main__":
app()
+38
View File
@@ -1,7 +1,9 @@
import json
import os
import random
import re
import shutil
import zipfile
from pathlib import Path
from jinja2 import Environment, FileSystemLoader
@@ -515,3 +517,39 @@ class Build:
page = solution_template.render(question=question, solution=solution, number=solution_file.stem)
page = self.__build_page(page, course_wrapper=False)
file.write(page)
def build_zip(self, zip_name: str | None = None) -> Path:
"""Create a zip archive of the complete build output directory.
The zip file is written into the build directory itself and is excluded
from the archive contents.
"""
build_dir = self.config.p_build
build_dir.mkdir(parents=True, exist_ok=True)
zip_path = build_dir / (zip_name if zip_name is not None else f"{build_dir.name}.zip")
zip_path = zip_path.resolve()
# If a previous archive exists, remove it first to avoid zipping stale data.
if zip_path.exists():
zip_path.unlink()
tqdm.write(f"Creating zip archive: {zip_path}")
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
# os.walk includes dotfiles; sort for stable archives.
for root, dirs, files in os.walk(build_dir):
dirs.sort()
files.sort()
root_path = Path(root)
for filename in files:
file_path = (root_path / filename).resolve()
if file_path == zip_path:
continue
arcname = file_path.relative_to(build_dir.resolve())
zf.write(file_path, arcname=arcname)
return zip_path