-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgenerate_bootstrap_json.py
executable file
·82 lines (64 loc) · 2.31 KB
/
generate_bootstrap_json.py
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env spack-python
"""Produce a bootstrap json file for a selected package"""
import glob
import hashlib
import json
import os
import sys
import spack.deptypes as dt
import spack.spec
import spack.traverse
# Each entry in clingo.json has the following keys:
#
# "spec": root spec to be matched
# "binaries": list of tuples (pkg name, dag hash, sha256 sum)
def sha256(path):
fn = hashlib.sha256()
with open(path, "rb") as f:
fn.update(f.read())
return fn.hexdigest()
def tarball_hash(path: str):
# extract hash from /path/to/<...>-<hash>.spack
name, _ = os.path.splitext(os.path.basename(path))
return name.split("-")[-1]
def run(pkg: str, deps=dt.NONE, python: bool = False):
name = "clingo-bootstrap" if pkg == "clingo" else pkg
shas = {
tarball_hash(tarball): sha256(tarball)
for tarball in glob.glob("./build_cache/**/*.spack", recursive=True)
}
specs = [
spack.spec.Spec.from_specfile(f) for f in glob.glob("./build_cache/*.json") if name in f
]
assert len(specs) > 0, f"No specs found for {name}"
fmt = "{name}{@version}{%compiler.name} platform={platform} target={target}"
if python:
fmt_spec = lambda s: f"{s.format(fmt)} ^python@{s.dependencies('python')[0].version}"
else:
fmt_spec = lambda s: s.format(fmt)
mirror_info = [
{
"spec": fmt_spec(s),
"binaries": [
(s.name, s.dag_hash(), shas[s.dag_hash()])
for s in reversed(list(s.traverse(order="topo", deptype=deps)))
if not s.external
],
}
for s in specs
]
# sort as strings, cause Spec instances with deps don't sort properly
mirror_info.sort(key=lambda x: x["spec"])
with open(f"./{pkg}.json", "w") as f:
json.dump({"verified": mirror_info}, f, sort_keys=True, indent=2)
if __name__ == "__main__":
assert len(sys.argv) == 2, f"Usage: {sys.argv[0]} <clingo|gnupg|patchelf>"
pkg = sys.argv[1]
# unfortunately we refer to clingo-bootstrap by alias "clingo"
assert pkg in ("clingo", "gnupg", "patchelf")
run(
pkg,
# clingo is special: statically links libstdc++ and other deps are loaded by interpreter
deps=dt.NONE if pkg == "clingo" else dt.LINK | dt.RUN,
python=pkg == "clingo",
)