Files
ttree/scripts/release/checksums.py
T

43 lines
1.4 KiB
Python

#!/usr/bin/env python3
"""Portable SHA-256 manifests shared by Windows, macOS and publication."""
import argparse
import hashlib
from pathlib import Path
def digest(path):
with path.open("rb") as source:
return hashlib.file_digest(source, "sha256").hexdigest()
def write(directory, name):
paths = sorted(p for p in directory.iterdir()
if p.is_file() and p.name != name and not p.name.endswith(".sha256"))
if not paths:
raise ValueError("no assets to checksum")
(directory / name).write_text("".join(f"{digest(p)} {p.name}\n" for p in paths))
def check(directory, name):
lines = (directory / name).read_text().splitlines()
if not lines:
raise ValueError("empty checksum manifest")
for line in lines:
expected, filename = line.split(" ", 1)
if Path(filename).name != filename or filename in (".", ".."):
raise ValueError("unsafe checksum path")
if digest(directory / filename) != expected:
raise ValueError(f"checksum mismatch: {filename}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("directory", type=Path)
parser.add_argument("--write")
parser.add_argument("--check", action="append", default=[])
args = parser.parse_args()
for name in args.check:
check(args.directory, name)
if args.write:
write(args.directory, args.write)