#!/usr/bin/env python3 """Write a haikuports recipe for oxy or oh (oxygen#156, #157) from a release's source tarball, NAME-VERSION-src.tar.gz, as the release job attaches it: the tarball itself from the release's stable download address, and every crates.io crate in its Cargo.lock as a source of its own with its checksum, vendored offline in BUILD() as haikuports' Rust recipes (ripgrep) do. make-recipe.py oxy|oh SRC_TARBALL VERSION > NAME-VERSION.recipe """ import hashlib import sys import tarfile import tomllib PORTS = { "oxy": { "repo": "oxygen", "package": "oxy", "summary": "A version control system of signed, commuting changes, with Git interop", "description": [ "oxy is the command line of Oxygen, a version control system built on", "patch theory: changes commute, conflicts are recorded rather than blocking,", "every change can be signed, and a trust policy says who may move what. It", "imports and exports Git history, clones from OxygenHub and other Oxygen", "hosts, and keeps repositories on disk or in S3, GCS or Azure buckets.", ], "docs": "README.md LICENSE*", "test": "oxy-core", }, "oh": { "repo": "oxygenhub", "package": "oh", "summary": "The command line of OxygenHub, the forge for Oxygen repositories", "description": [ "oh talks to an OxygenHub (such as https://oxygenhub.io): issues, proposals", "and their reviews, releases, Flow runs, their logs and reports, and checks,", "from the terminal. It works alongside oxy, the Oxygen version control", "client.", ], "docs": "README.md LICENSE docs/oh.md", "test": "hub-api", }, } name, tarball, version = sys.argv[1], sys.argv[2], sys.argv[3] port = PORTS[name] prefix = f"{port['repo']}-{version}" with tarfile.open(tarball) as t: lock = tomllib.load(t.extractfile(f"{prefix}/Cargo.lock")) crates = sorted( (p["name"], p["version"], p["checksum"]) for p in lock["package"] if p.get("source", "").startswith("registry+") ) sha = hashlib.sha256(open(tarball, "rb").read()).hexdigest() out = [] w = out.append w(f'SUMMARY="{port["summary"]}"') w('DESCRIPTION="' + " \\\n".join(port["description"]) + '"') w(f'HOMEPAGE="https://oxygenhub.io/andymccall/{port["repo"]}"') w('COPYRIGHT="2026 Andy McCall"') w('LICENSE="MIT\n\tApache v2"') w('REVISION="1"') w(f'SOURCE_URI="$HOMEPAGE/releases/download/v$portVersion/{name}-$portVersion-src.tar.gz"') w(f'CHECKSUM_SHA256="{sha}"') w(f'SOURCE_DIR="{port["repo"]}-$portVersion"') for i, (crate, ver, ck) in enumerate(crates, start=2): w(f'SOURCE_URI_{i}="https://static.crates.io/crates/{crate}/{crate}-{ver}.crate"') w(f'CHECKSUM_SHA256_{i}="{ck}"') w(f'SOURCE_FILENAME_{i}="{crate}-{ver}.tar.gz"') last = len(crates) + 1 w(f''' ARCHITECTURES="!all x86_64" PROVIDES=" {name}$secondaryArchSuffix = $portVersion cmd:{name} " REQUIRES=" haiku$secondaryArchSuffix lib:libzstd$secondaryArchSuffix " BUILD_REQUIRES=" haiku${{secondaryArchSuffix}}_devel devel:libzstd$secondaryArchSuffix " BUILD_PREREQUIRES=" cmd:gcc$secondaryArchSuffix cmd:pkg_config$secondaryArchSuffix cmd:rustc$secondaryArchSuffix " BUILD() {{ export CARGO_HOME=$sourceDir/../cargo vendor=$CARGO_HOME/haiku mkdir -p "$vendor" for i in $(seq 2 {last}); do eval "srcDir=\\$sourceDir$i" eval "sha256sum=\\$CHECKSUM_SHA256_$i" set -- "$srcDir"/* ln -sf "$1" "$vendor" cat <<-EOF >"$vendor/${{1##*/}}/.cargo-checksum.json" {{ "package": "$sha256sum", "files": {{}} }} EOF done cat <<-EOF >"$CARGO_HOME"/config.toml [source.haiku] directory = "$vendor" [source.crates-io] replace-with = "haiku" EOF # The bundled zstd's hidden symbols break the link on Haiku: use the system's. export ZSTD_SYS_USE_PKG_CONFIG=1 export OXY_BUILD=v$portVersion cargo build --release --frozen -p {port["package"]} }} INSTALL() {{ install -v -m 755 -d "$prefix"/bin "$docDir" install -v -m 755 ./target/release/{name} "$prefix"/bin install -v -m 644 {port["docs"]} "$docDir" }} TEST() {{ export CARGO_HOME=$sourceDir/../cargo export ZSTD_SYS_USE_PKG_CONFIG=1 cargo test --release --frozen -p {port["test"]} }}''') print("\n".join(out))