From 5e67634930d4ae179902f922361cb70c25bbeba6 Mon Sep 17 00:00:00 2001 From: Esteban Zimanyi Date: Thu, 3 Sep 2026 18:44:29 +0200 Subject: [PATCH] Hold the generated types package to the same regeneration as functions CI builds the committed functions/ snapshot, regenerates it from a freshly derived catalog and reports the drift; types/ arrives generated and no step regenerates it, so nothing would notice it drifting away from the catalog it is supposed to be a projection of. A generated tree nothing regenerates is a hand-written tree with a comment on top. `objectgen.py` RUNS `codegen.py` and then projects the object model, so one command regenerates both and neither can be refreshed without the other -- which matters because types/ calls the wrappers codegen emits, and a functions/ refreshed alone leaves the object layer calling a surface that has moved. The CI regeneration step and the refresh recipe both invoke it; its catalog argument now defaults to tools/meos-idl.json, where the refresh stages one, so the command reads the same in both places. The committed-snapshot build and the drift report widen to cover both packages. That build is the step that FAILS, and it is where a consumer breakage is caught: a snapshot which no longer compiles is invisible to a job that regenerates first. MEASURED on the catalog this tree was generated from: regeneration reproduces the committed functions/ and types/ with 0 files differing against 116 tracked type files, so the committed tree IS the projection rather than a snapshot of one. `go build ./functions ./types`, `go build ./...` over all 12 packages, `go vet ./types` and the parity gate all exit 0. --- .github/workflows/build.yml | 26 +++++++++++++++----------- tools/objectgen.py | 9 ++++++--- tools/refresh.conf | 10 ++++++---- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2980a50..832addf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,17 +59,21 @@ jobs: CGO_LDFLAGS: -L/usr/local/lib -lmeos LD_LIBRARY_PATH: /usr/local/lib run: | - if ! go build ./functions; then - echo "::error::the committed functions/ snapshot does not build against this libmeos." - echo "Refresh it: python3 tools/codegen.py against a freshly derived meos-idl.json, then commit functions/." + if ! go build ./functions ./types; then + echo "::error::the committed functions/ or types/ snapshot does not build against this libmeos." + echo "Refresh them: python3 tools/objectgen.py against a freshly derived meos-idl.json, then commit both." exit 1 fi - name: Stage the derived catalog for the generator run: cp "${{ steps.provision.outputs.catalog-path }}" tools/meos-idl.json - - name: Regenerate the functions package from the catalog - run: python3 tools/codegen.py + # objectgen RUNS codegen and then projects the object model, so one command + # regenerates both packages and neither can be refreshed without the other. + # types/ calls the wrappers codegen emits, so a functions/ refreshed alone + # leaves the object layer calling a surface that has moved. + - name: Regenerate the functions and types packages from the catalog + run: python3 tools/objectgen.py - name: Report drift between the committed and freshly derived functions package run: | @@ -80,19 +84,19 @@ jobs: # The committed functions/ is a convenience snapshot for `go get` # consumers; refresh it by running 'python3 tools/codegen.py' against a # freshly derived meos-idl.json and committing the result. - if ! git diff --quiet -- functions/; then - echo "::notice::functions/ differs from the freshly derived catalog (snapshot lags MobilityDB master):" - git diff --stat -- functions/ + if ! git diff --quiet -- functions/ types/; then + echo "::notice::the generated packages differ from the freshly derived catalog (snapshot lags MobilityDB master):" + git diff --stat -- functions/ types/ else - echo "functions/ snapshot is in sync with the derived catalog." + echo "functions/ and types/ snapshots are in sync with the derived catalog." fi - - name: Build the generated functions package against the all-families libmeos + - name: Build the generated functions and types packages against the all-families libmeos env: CGO_CFLAGS: -I/usr/local/include -I/usr/include/h3 CGO_LDFLAGS: -L/usr/local/lib -lmeos LD_LIBRARY_PATH: /usr/local/lib - run: go build ./functions + run: go build ./functions ./types - name: Run the portable-parity gate env: diff --git a/tools/objectgen.py b/tools/objectgen.py index 06ff37b..4c0c565 100644 --- a/tools/objectgen.py +++ b/tools/objectgen.py @@ -395,14 +395,17 @@ def base_file(self) -> str: def main() -> int: + repo = Path(__file__).resolve().parent.parent + ap = argparse.ArgumentParser() - ap.add_argument("catalog", type=Path) + ap.add_argument("catalog", type=Path, nargs="?", + default=repo / "tools" / "meos-idl.json", + help="the catalog to project (default: tools/meos-idl.json, " + "where the refresh stages it)") ap.add_argument("--report", action="store_true", help="print what each class deferred and why") args = ap.parse_args() - repo = Path(__file__).resolve().parent.parent - # Fill codegen.SIGNATURES by RUNNING the flat generator, so which functions have a # wrapper is decided in one place. Re-deriving that here would be a second copy of # its exclusions, and the two would drift. diff --git a/tools/refresh.conf b/tools/refresh.conf index a653b03..47fe948 100644 --- a/tools/refresh.conf +++ b/tools/refresh.conf @@ -1,8 +1,10 @@ # refresh.conf — GoMEOS's last leg for tools/refresh-binding.sh (in MEOS-API). # The chain (MobilityDB -> catalog + libmeos) is shared; only these differ per binding. # BUILD_CMD runs from / with $PREFIX (the libmeos install prefix) and $CATALOG -# exported; $SKIP_TESTS is set when --skip-tests is passed. tools/codegen.py reads the catalog -# staged at CATALOG_DEST and regenerates the committed functions/ package. +# exported; $SKIP_TESTS is set when --skip-tests is passed. tools/objectgen.py reads the catalog +# staged at CATALOG_DEST, runs tools/codegen.py to regenerate the committed functions/ package, +# and projects the catalog's object model into types/. One command regenerates both, so neither +# can be refreshed without the other -- types/ calls the wrappers codegen emits. # # PKG_CONFIG_PATH names the prefix this run just built. functions/cgo.go says # `#cgo pkg-config: meos`, so cgo resolves whichever meos.pc the default search path answers @@ -15,6 +17,6 @@ ENGINE=go BUILD_DIR=. BUILD_LIBMEOS=true CATALOG_DEST=tools/meos-idl.json -BUILD_CMD='python3 tools/codegen.py - PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" CGO_LDFLAGS="-L$PREFIX/lib -lmeos" LD_LIBRARY_PATH="$PREFIX/lib" go build ./functions +BUILD_CMD='python3 tools/objectgen.py + PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" CGO_LDFLAGS="-L$PREFIX/lib -lmeos" LD_LIBRARY_PATH="$PREFIX/lib" go build ./functions ./types [ -n "${SKIP_TESTS:-}" ] || CGO_ENABLED=0 go test ./tools/parity/'