feat(cli): add cargo sqlx prepare --per-crate - #4382
Draft
macalinao wants to merge 1 commit into
Draft
Conversation
Generates a `.sqlx` directory next to each workspace crate's `Cargo.toml` instead of a single one at the workspace root, so editing one crate's queries only touches that crate's query data. The read side already supported this: `expand_input` looks for each query file in `$CARGO_MANIFEST_DIR/.sqlx` before falling back to the workspace root, per file. Only the write side was workspace-wide, because `prepare` sets one `SQLX_OFFLINE_DIR` for a single `cargo check` over the whole workspace. Rather than run `cargo check` once per crate — which writes a crate's query data into whichever sibling happened to trigger its first compile — the macros now route their own save directory. `sqlx-cli` sets `SQLX_OFFLINE_PER_CRATE`, and each expansion saves to `$SQLX_OFFLINE_DIR/$CARGO_PKG_NAME`, which is correct regardless of build order and still only needs one `cargo check`. That staging tree lives under `target/`, and the CLI moves each crate's files into its `.sqlx` afterwards. `--check` reuses the same layout to compare against the checked-in data without touching it, and reports failures per crate. Only `query-*.json` files are ever written or deleted, so anything else in a `.sqlx` directory is left alone. `--per-crate` implies `--workspace` and rejects `--all`, since crates outside the workspace have no crate directory to write to. After a successful run, query data left at the workspace root by a previous `--workspace` run is reported as no longer generated or checked. Claude-Session: https://claude.ai/code/session_011CmjiD9jHNqmdTptXkMu4j
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
cargo sqlx prepare --per-crate, which generates a.sqlxdirectory next to each workspace crate'sCargo.tomlinstead of a single one at the workspace root. Editing one crate's queries then only touches that crate's query data.How
The read side already supported this.
expand_inputlooks for each query file in$CARGO_MANIFEST_DIR/.sqlxbefore falling back to the workspace root, and it does so per file, so a crate can use either layout (or both). Only the write side was workspace-wide, becausepreparesets oneSQLX_OFFLINE_DIRfor a singlecargo checkcovering the whole workspace.The obvious alternative — loop over members running
cargo check -p <member>withSQLX_OFFLINE_DIR=<member>/.sqlx— is wrong: when crate A is checked, its workspace-member dependencies compile for the first time in that same invocation, so their query data lands inA/.sqlx. Avoiding that needs a warm-up build plus reverse-topological ordering, and Ncargo checkinvocations.Instead the macros route their own save directory.
sqlx-clisetsSQLX_OFFLINE_PER_CRATE, and each expansion saves to$SQLX_OFFLINE_DIR/$CARGO_PKG_NAME. That is correct regardless of build order and still needs only onecargo check.The staging tree lives under
target/, and the CLI moves each crate's files into its.sqlxafterwards.--checkreuses the same layout to compare against the checked-in data without touching it, and attributes failures to the crate they came from:Notes
query-*.jsonfiles are written or deleted, so anything else a user keeps in.sqlxsurvives. A.sqlxdirectory emptied of query data is removed if nothing else is in it.--per-crateimplies--workspaceand rejects--all, since crates outside the workspace have no crate directory to write to.--workspacerun is reported as no longer generated or checked, since the macros still fall back to it.save_innow creates its target directory, so a dependency outside the workspace that expands a query mid-prepare doesn't fail the build.Testing
sqlx-cli/src/prepare.rscovering the crate/directory mapping, staging reset, install (stale replacement, preserving non-query files, creating and removing directories), the check comparison, and the stale-workspace-data detection.sqlx-macros-core/src/query/metadata.rscovering save-directory resolution.sqlx-cli/tests/prepare.rsfor the flag validation.--per-cratewrites each crate's queries to its own.sqlxwith a shared query duplicated in both;SQLX_OFFLINE=true cargo checkbuilds against them;--checkpasses when current and fails naming the right crate after a query changes; the stale-workspace warning fires; and--workspacestill produces a single root.sqlxand passes--check.https://claude.ai/code/session_011CmjiD9jHNqmdTptXkMu4j