-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathartifacts.py
More file actions
46 lines (37 loc) · 1.42 KB
/
artifacts.py
File metadata and controls
46 lines (37 loc) · 1.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from __future__ import annotations
import hashlib
import json
from dataclasses import dataclass
from importlib import resources
from pathlib import Path
@dataclass(frozen=True)
class ArtifactRecord:
name: str
path: str
sha256: str
def load_artifact_manifest() -> dict[str, ArtifactRecord]:
manifest_text = resources.files("timecapsulesmb.assets").joinpath("artifact-manifest.json").read_text()
raw = json.loads(manifest_text)
return {
name: ArtifactRecord(name=name, path=entry["path"], sha256=entry["sha256"])
for name, entry in raw["artifacts"].items()
}
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as fh:
for chunk in iter(lambda: fh.read(65536), b""):
digest.update(chunk)
return digest.hexdigest()
def validate_artifacts(distribution_root: Path) -> list[tuple[str, bool, str]]:
results: list[tuple[str, bool, str]] = []
for record in load_artifact_manifest().values():
path = distribution_root / record.path
if not path.exists():
results.append((record.name, False, f"missing {record.path}"))
continue
actual = sha256_file(path)
if actual != record.sha256:
results.append((record.name, False, f"checksum mismatch for {record.path}"))
continue
results.append((record.name, True, f"validated {record.path}"))
return results