postjevsql.git / tools / cargo-gen

Chapter 20: cargo-gen, a Cargo workspace written from the buck graph

This repository is built by buck2, and buck's BUCK files are the one place a crate's dependencies are written. But most Rust tools, and most Rust people, expect Cargo: a Cargo.toml per crate and one at the root. Keeping both by hand would mean two lists of every dependency, which agree on the day they are written and never again.

So the Cargo files are generated. Each first_party_* macro in build/defs.bzl quietly emits a small JSON file beside its target, naming its kind, its crate root and its dependencies. This tool reads all of those, plus the version, edition and supported majors from build/defs.bzl and the version requirements from third-party/Cargo.toml, and writes the root Cargo.toml, one manifest per package, and the extension's src/bin/pgrx_embed.rs.

flowchart LR
  D["build/defs.bzl: VERSION, RUST_EDITION, PG_MAJORS"] --> G
  M["each target's -cargo JSON"] --> G
  T["third-party/Cargo.toml: version requirements"] --> G
  G["cargo-gen generate"] --> O[":manifests"]
  O -->|"drift test compares"| C["the committed Cargo.toml files"]
  O -->|"buck2 run :update"| C

Every crate that reaches pgrx gets a pgNN feature for each supported major, the newest as the default, which is how cargo users pick a major (--no-default-features --features pg17). Every manifest says MIT OR Apache-2.0 and "The postjevsql Authors", and none names a repository. The integration tests stay buck-only: they need buck to tell them where the built extension is.

Try it. After changing a dependency in a BUCK file, run nix develop -c buck2 run //tools/cargo-gen:update and look at git diff: the manifests have caught up. Skip it, and //tools/cargo-gen:drift fails until you do.

For the people who maintain it

PathWhat
src/The tool. Chapter 21.
BUCK:cargo-gen; PACKAGES, the one hand-kept list of first-party packages; :manifests (what the BUCK files imply), :committed (what is in the checkout), :drift and :update.
drift.rsThe drift test: fails, naming the file, when a committed manifest differs from the generated one.
Cargo.tomlIts own manifest, generated by itself.

← Previous: Chapter 19, pgrx-schema/src/ · Up: tools · Next: Chapter 21, cargo-gen/src/ →