generate: a call site, so this repo can regenerate and check itself

pkg/hanzoai/cloud is generated, and until now this was the only client of the
seven with no in-repo way to produce or verify it. The driver lives in
hanzoai/openapi (generate.py + sdks.yaml), so a checkout of python-sdk alone
could not even ask whether its committed client matched the document.

scripts/generate.sh is a CALL SITE, not a second driver — the same eight lines
java-sdk and kotlin-sdk already run, ending in `generate.py python --repo $PWD`.
That distinction is the whole point: the previous scripts/generate.sh here was a
real second driver, it did `rm -rf pkg/hanzoai`, and it was deleted for that.
This one cannot, because generate.py owns exactly the one take path sdks.yaml
names.

Measured against hanzo.yaml@9781a56: +159 -110 ~135. That drift is what the gate
exists to refuse; it is reported here, not silently regenerated, because the
fleet's regeneration is one coordinated wave and not seven.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-08-01 11:19:11 -07:00
co-authored by Hanzo Dev
parent 3ada3bc85b
commit 57756128d9
2 changed files with 56 additions and 0 deletions
+13
View File
@@ -76,3 +76,16 @@ test:
for b in bad: print("FAIL", b, file=sys.stderr)
sys.exit(1 if (bad or not ok) else 0)
'
- name: codegen-drift-check
# The client is generated, so the only thing that can rot is the committed
# copy — and the import test above cannot see that rot, because a client
# generated from last week's document imports perfectly. This regenerates
# from hanzoai/openapi and fails if what is in git is not what the document
# produces. Needs SPEC_TOKEN — hanzoai/openapi is private.
#
# It is the last of the seven clients to get one, and it was the only one
# with no in-repo way to regenerate at all: the driver lives in
# hanzoai/openapi, so without scripts/generate.sh this repo could not even
# ask the question.
run: ./scripts/generate.sh --check
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Regenerate pkg/hanzoai/cloud/ from the Hanzo OpenAPI document.
#
# This is a CALL SITE, not a generator invocation. The invocation is logic and
# lives once, in hanzoai/openapi `generate.py`; every per-language knob —
# generator, library, package name — is data in `sdks.yaml` beside it. Nothing
# about how this client is produced is written down in this repo, so there is
# nothing here that can drift on its own. It is the same eight lines java-sdk
# and kotlin-sdk already run, and deliberately not a second driver: the old
# scripts/generate.sh here WAS one, it did `rm -rf pkg/hanzoai`, and it was
# deleted for that reason. This one cannot — `generate.py` owns exactly the one
# `take` path sdks.yaml names, `hanzoai/cloud -> pkg/hanzoai/cloud`.
#
# ./scripts/generate.sh # regenerate in place
# ./scripts/generate.sh --check # non-zero if the committed client drifted
#
# hanzoai/openapi is PRIVATE, so raw.githubusercontent.com 404s it and a clone
# needs credentials: SPEC_TOKEN, else GH_TOKEN, else GITHUB_TOKEN, else ssh.
# Point OPENAPI at a checkout you already have to skip the clone entirely.
#
# Requires: python3 (+pyyaml), java 11+, git.
set -euo pipefail
cd "$(dirname "$0")/.."
OPENAPI="${OPENAPI:-}"
SPEC_REPO="${SPEC_REPO:-hanzoai/openapi}"
SPEC_REF="${SPEC_REF:-main}"
if [ -z "$OPENAPI" ]; then
OPENAPI="$(mktemp -d "${TMPDIR:-/tmp}/hanzo-openapi.XXXXXX")"
trap 'rm -rf "$OPENAPI"' EXIT
TOKEN="${SPEC_TOKEN:-${GH_TOKEN:-${GITHUB_TOKEN:-}}}"
if [ -n "$TOKEN" ]; then
echo "cloning private ${SPEC_REPO}@${SPEC_REF} with a token (raw.githubusercontent.com 404s private paths)"
git clone --depth 1 --branch "$SPEC_REF" \
"https://x-access-token:${TOKEN}@github.com/${SPEC_REPO}.git" "$OPENAPI" >/dev/null 2>&1
else
echo "cloning ${SPEC_REPO}@${SPEC_REF} over ssh; set SPEC_TOKEN/GH_TOKEN/GITHUB_TOKEN or OPENAPI to override"
git clone --depth 1 --branch "$SPEC_REF" "[email protected]:${SPEC_REPO}.git" "$OPENAPI" >/dev/null
fi
fi
exec python3 "$OPENAPI/generate.py" python --repo "$PWD" "$@"