oni.git

oni

~ A static Git browser written in Rust.
git clone https://github.com/debuman/oni.git

scripts/package_site.py (1874B)

      1 #!/usr/bin/env python3
      2 """Package only generated regular files, preserving dot-prefixed repository names."""
      3 
      4 import argparse
      5 from pathlib import Path
      6 import tarfile
      7 
      8 ROOT = Path(__file__).resolve().parents[1]
      9 MAX_ARCHIVE_BYTES = 1024 * 1024 * 1024
     10 
     11 
     12 def package(public, output):
     13     public = public.resolve()
     14     output = output.resolve()
     15     if output.is_relative_to(public):
     16         raise ValueError("Place the deployment archive outside the generated site")
     17     if not (public / "index.html").is_file():
     18         raise ValueError("The generated site has no index.html")
     19     paths = sorted(public.rglob("*"))
     20     total = 0
     21     for path in paths:
     22         if path.is_symlink() or path.is_junction() or not (path.is_file() or path.is_dir()):
     23             raise ValueError(f"Deployment contains a link or special file: {path}")
     24         if ".git" in path.relative_to(public).parts:
     25             raise ValueError("Git metadata must never be deployed")
     26         if path.is_file():
     27             total += path.stat().st_size
     28         total += 2048
     29     if total >= MAX_ARCHIVE_BYTES:
     30         raise ValueError("Generated site exceeds the 1 GiB deployment limit")
     31     output.parent.mkdir(parents=True, exist_ok=True)
     32     with tarfile.open(output, "w", format=tarfile.PAX_FORMAT, dereference=True) as archive:
     33         for path in paths:
     34             archive.add(path, arcname=path.relative_to(public).as_posix(), recursive=False)
     35     if output.stat().st_size >= MAX_ARCHIVE_BYTES:
     36         raise ValueError("Deployment archive exceeds the 1 GiB limit")
     37     print(f"Packaged {len(paths)} entries into {output} ({output.stat().st_size:,} bytes)")
     38 
     39 
     40 def main():
     41     parser = argparse.ArgumentParser(description=__doc__)
     42     parser.add_argument("--output", type=Path, required=True)
     43     args = parser.parse_args()
     44     package(ROOT / "public", args.output)
     45 
     46 
     47 if __name__ == "__main__":
     48     main()