ictlogin/scripts/build_release.py

78 lines
2.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""Build the dependency-free ICT login zipapp and its checksum."""
from __future__ import annotations
import argparse
import hashlib
import os
import shutil
import tempfile
from pathlib import Path
from zipapp import create_archive
ROOT = Path(__file__).resolve().parents[1]
DEFAULT_OUTPUT = ROOT / "dist" / "ictlogin.pyz"
def _copy_source(source: Path, target: Path) -> None:
target.mkdir(parents=True, exist_ok=True)
shutil.copytree(
source,
target / "ictlogin",
ignore=shutil.ignore_patterns("__pycache__", "*.pyc", "*.pyo", "*.egg-info"),
)
def _sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def build(output: Path, checksum_path: Path) -> None:
output.parent.mkdir(parents=True, exist_ok=True)
staging_root = Path(tempfile.mkdtemp(prefix="ictlogin-build-"))
temporary_output = output.with_name(output.name + ".tmp")
try:
_copy_source(ROOT / "src" / "ictlogin", staging_root)
create_archive(
staging_root,
temporary_output,
interpreter="/usr/bin/env python3",
main="ictlogin.cli:main",
compressed=True,
)
os.chmod(temporary_output, 0o755)
os.replace(temporary_output, output)
digest = _sha256(output)
checksum_path.parent.mkdir(parents=True, exist_ok=True)
checksum_path.write_text(f"{digest} {output.name}\n", encoding="ascii")
os.chmod(checksum_path, 0o644)
finally:
if temporary_output.exists():
temporary_output.unlink()
shutil.rmtree(staging_root, ignore_errors=True)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--output", type=Path, default=DEFAULT_OUTPUT, help="output .pyz path"
)
parser.add_argument(
"--checksum", type=Path, help="checksum path (defaults to OUTPUT.sha256)"
)
args = parser.parse_args()
checksum_path = args.checksum or Path(str(args.output) + ".sha256")
build(args.output.resolve(), checksum_path.resolve())
print(f"built {args.output}")
print(f"sha256 {checksum_path}")
if __name__ == "__main__":
main()