from __future__ import annotations
import hashlib, json, sys, urllib.request, pathlib, tomllib
CRATE_URL = "https://static.crates.io/crates/{name}/{name}-{version}.crate"
def fetch(url: str) -> bytes:
req = urllib.request.Request(url, headers={"User-Agent": "agtop-port-gen/1"})
with urllib.request.urlopen(req, timeout=60) as r:
return r.read()
def main() -> int:
here = pathlib.Path(__file__).resolve().parent
lock_path = here.parent / "Cargo.lock"
cargo = tomllib.loads(lock_path.read_text())
pkgs = cargo.get("package", [])
crates = []
for p in pkgs:
src = p.get("source", "")
if not src.startswith("registry+"):
continue
crates.append((p["name"], p["version"]))
crates.sort()
cargo_crates_lines = []
distinfo_lines = []
for name, version in crates:
url = CRATE_URL.format(name=name, version=version)
print(f" fetching {name}-{version}", file=sys.stderr)
try:
blob = fetch(url)
except Exception as e:
print(f" ERROR {name}-{version}: {e}", file=sys.stderr)
return 2
sha = hashlib.sha256(blob).hexdigest()
size = len(blob)
cargo_crates_lines.append(f"\t{name}-{version} \\")
distinfo_lines.append(
f"SHA256 (rust/crates/{name}-{version}.crate) = {sha}\n"
f"SIZE (rust/crates/{name}-{version}.crate) = {size}"
)
if cargo_crates_lines:
cargo_crates_lines[-1] = cargo_crates_lines[-1].rstrip(" \\")
print("# ── CARGO_CRATES (paste into Makefile) ──────────────────────────────")
print("CARGO_CRATES=\t\\")
print("\n".join(cargo_crates_lines))
print()
print("# ── distinfo (paste into distinfo, in addition to the source tarball) ──")
print("\n".join(distinfo_lines))
print(f"\n# Total crates: {len(crates)}", file=sys.stderr)
return 0
if __name__ == "__main__":
sys.exit(main())