"""The package managers' entries for a wai-quantum release, from the SHA-256 files attached to it: python3 release/formulae.py Writes /wai-quantum.rb (a Homebrew formula for macOS and Linux) and /wai-quantum.json (a Scoop manifest for Windows). A platform whose archive is not attached is left out, and stderr says so; with none at all, it fails. """ import json import os import pathlib import sys import urllib.request version, tag, api, repo, public, out = sys.argv[1:7] token = os.environ.get("FORGE_TOKEN", "") # A user agent of our own: the public address refuses the library's default one. headers = {"User-Agent": "wai-quantum-release"} if token: headers["Authorization"] = f"token {token}" # The forge's own address, as the API's: the SHA-256 files are read there, over the # private network, not through the public address the formula points users to. web = api.rsplit("/api/v1", 1)[0] def get(url): with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=60) as r: return r.read() release = json.loads(get(f"{api}/repos/{repo}/releases/tags/{tag}")) assets = {a["name"]: a for a in release.get("assets", [])} def digest(archive): """The SHA-256 its .sha256 file states, or None when either is missing.""" if archive not in assets or archive + ".sha256" not in assets: print(f"note: {archive} is not attached; left out", file=sys.stderr) return None return get(f"{web}/{repo}/releases/download/{tag}/{archive}.sha256").decode().split()[0] def url(archive): return f"{public}/releases/download/{tag}/{archive}" targets = { ("macos", "arm"): "aarch64-apple-darwin", ("macos", "intel"): "x86_64-apple-darwin", ("linux", "arm"): "aarch64-unknown-linux-musl", ("linux", "intel"): "x86_64-unknown-linux-musl", } blocks = {} for (os_name, cpu), triple in targets.items(): archive = f"wai-quantum-{version}-{triple}.tar.gz" sha = digest(archive) if sha: blocks.setdefault(os_name, []).append(f' on_{cpu} do\n url "{url(archive)}"\n sha256 "{sha}"\n end\n') win = f"wai-quantum-{version}-x86_64-pc-windows-msvc" win_sha = digest(win + ".zip") if not blocks and not win_sha: sys.exit("no archive is attached to the release") formula = f'''class WaiQuantum < Formula desc "OpenQASM programs run as the WAI quantum job service runs them, signed" homepage "https://wai.transaction.science/quantum-studio/" version "{version}" license "Apache-2.0" ''' for os_name in ("macos", "linux"): if os_name in blocks: formula += f" on_{os_name} do\n" + "".join(blocks[os_name]) + " end\n" formula += ''' def install bin.install "wai-quantum" generate_completions_from_executable(bin/"wai-quantum", "completions") end test do assert_match "did:key:z6Mk", shell_output("#{bin}/wai-quantum key --demo-key") end end ''' pathlib.Path(out, "wai-quantum.rb").write_text(formula) sha = win_sha if sha: manifest = { "version": version, "description": "OpenQASM programs run as the WAI quantum job service runs them, signed", "homepage": "https://wai.transaction.science/quantum-studio/", "license": "Apache-2.0", "architecture": {"64bit": {"url": url(win + ".zip"), "hash": sha, "extract_dir": win}}, "bin": "wai-quantum.exe", } pathlib.Path(out, "wai-quantum.json").write_text(json.dumps(manifest, indent=2) + "\n") print(f"wrote the formula{' and the manifest' if sha else ''} for wai-quantum {version}")