diff --git a/sqlx-cli/README.md b/sqlx-cli/README.md index ae575d5b5f..4f62138847 100644 --- a/sqlx-cli/README.md +++ b/sqlx-cli/README.md @@ -133,6 +133,13 @@ to generate a single `.sqlx` directory at the root of the workspace. cargo sqlx prepare --workspace ``` +When `--workspace` is used, SQLx also checks every workspace member. Cargo options such as +`--all-targets` and `--all-features` can still be forwarded after `--`: + +```bash +cargo sqlx prepare --workspace -- --all-targets --all-features +``` + Check this directory into version control and an active database connection will no longer be needed to build your project. diff --git a/sqlx-cli/src/prepare.rs b/sqlx-cli/src/prepare.rs index f3688add2a..de8f55de4e 100644 --- a/sqlx-cli/src/prepare.rs +++ b/sqlx-cli/src/prepare.rs @@ -31,6 +31,26 @@ impl PrepareCtx<'_> { Ok(manifest_dir(&self.cargo)?.join(".sqlx")) } } + + /// Arguments passed to the `cargo check` invocation that prepares query metadata. + /// + /// `--workspace` on `sqlx prepare` controls both the location of the generated `.sqlx` + /// directory and which workspace packages are recompiled. It must also select all workspace + /// packages for the Cargo invocation; otherwise a workspace root which is itself a package + /// only checks that root package by default. + fn cargo_check_args(&self) -> Vec { + cargo_check_args(self.workspace, &self.cargo_args) + } +} + +fn cargo_check_args(workspace: bool, cargo_args: &[String]) -> Vec { + let mut args = cargo_args.to_vec(); + + if workspace && !args.iter().any(|arg| arg == "--workspace") { + args.push("--workspace".to_owned()); + } + + args } pub async fn run( @@ -179,7 +199,7 @@ fn run_prepare_step(ctx: &PrepareCtx, cache_dir: &Path) -> anyhow::Result<()> { let mut check_command = Command::new(&ctx.cargo); check_command .arg("check") - .args(&ctx.cargo_args) + .args(ctx.cargo_check_args()) .env("SQLX_TMP", tmp_dir) .env("SQLX_OFFLINE", "false") .env("SQLX_OFFLINE_DIR", cache_dir); @@ -372,6 +392,22 @@ mod tests { use super::*; use std::assert_eq; + #[test] + fn workspace_prepare_selects_all_workspace_packages() { + assert_eq!( + cargo_check_args(true, &["--all-targets".into(), "--all-features".into()]), + ["--all-targets", "--all-features", "--workspace"] + ); + } + + #[test] + fn workspace_prepare_does_not_duplicate_workspace_argument() { + assert_eq!( + cargo_check_args(true, &["--workspace".into()]), + ["--workspace"] + ); + } + #[test] fn minimal_project_recompile_action_works() -> anyhow::Result<()> { let sample_metadata_path = Path::new("tests")