mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
Query data is now stored in .sqlx/{query_hash}.json directly by the macro
invocations, rather than first writing to target/sqlx/{input_span_hash}.json
and then collecting those into sqlx-data.json separately.
118 lines
3.0 KiB
Rust
118 lines
3.0 KiB
Rust
use anyhow::bail;
|
|
use std::ffi::OsString;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
use std::time::SystemTime;
|
|
|
|
#[derive(Debug)]
|
|
pub struct PrepareCtx {
|
|
pub workspace: bool,
|
|
pub cargo: OsString,
|
|
pub cargo_args: Vec<String>,
|
|
pub manifest_dir: PathBuf,
|
|
pub target_dir: PathBuf,
|
|
pub workspace_root: PathBuf,
|
|
pub database_url: Option<String>,
|
|
}
|
|
|
|
pub fn run(ctx: &PrepareCtx) -> anyhow::Result<()> {
|
|
let root = if ctx.workspace {
|
|
&ctx.workspace_root
|
|
} else {
|
|
&ctx.manifest_dir
|
|
};
|
|
|
|
run_prepare_step(ctx, &root.join(".sqlx"))?;
|
|
|
|
println!(
|
|
"query data written to `.sqlx` in the current directory; \
|
|
please check this into version control"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn check(ctx: &PrepareCtx) -> anyhow::Result<()> {
|
|
let cache_dir = ctx.target_dir.join("sqlx");
|
|
run_prepare_step(ctx, &cache_dir)?;
|
|
|
|
// TODO: Compare .sqlx to target/sqlx
|
|
// * For files thta are only in the former, raise a warning
|
|
// * For files that are only in the latter, raise an error
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn run_prepare_step(ctx: &PrepareCtx, cache_dir: &Path) -> anyhow::Result<()> {
|
|
anyhow::ensure!(
|
|
Path::new("Cargo.toml").exists(),
|
|
r#"Failed to read `Cargo.toml`.
|
|
hint: This command only works in the manifest directory of a Cargo package."#
|
|
);
|
|
|
|
if cache_dir.exists() {
|
|
clear_cache_dir(cache_dir)?;
|
|
} else {
|
|
fs::create_dir(cache_dir)?;
|
|
}
|
|
|
|
let mut check_cmd = Command::new(&ctx.cargo);
|
|
if ctx.workspace {
|
|
let check_status = Command::new(&ctx.cargo).arg("clean").status()?;
|
|
|
|
if !check_status.success() {
|
|
bail!("`cargo clean` failed with status: {}", check_status);
|
|
}
|
|
|
|
check_cmd.arg("check").args(&ctx.cargo_args).env(
|
|
"RUSTFLAGS",
|
|
format!(
|
|
"--cfg __sqlx_recompile_trigger=\"{}\"",
|
|
SystemTime::UNIX_EPOCH.elapsed()?.as_millis()
|
|
),
|
|
);
|
|
} else {
|
|
check_cmd
|
|
.arg("rustc")
|
|
.args(&ctx.cargo_args)
|
|
.arg("--")
|
|
.arg("--emit")
|
|
.arg("dep-info,metadata")
|
|
// set an always-changing cfg so we can consistently trigger recompile
|
|
.arg("--cfg")
|
|
.arg(format!(
|
|
"__sqlx_recompile_trigger=\"{}\"",
|
|
SystemTime::UNIX_EPOCH.elapsed()?.as_millis()
|
|
));
|
|
}
|
|
|
|
// override database url
|
|
if let Some(database_url) = &ctx.database_url {
|
|
check_cmd.env("DATABASE_URL", database_url);
|
|
}
|
|
|
|
check_cmd
|
|
.env("SQLX_OFFLINE", "false")
|
|
.env("SQLX_OFFLINE_DIR", cache_dir);
|
|
|
|
println!("executing {:?}", check_cmd);
|
|
|
|
let check_status = check_cmd.status()?;
|
|
|
|
if !check_status.success() {
|
|
bail!("`cargo check` failed with status: {}", check_status);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn clear_cache_dir(path: &Path) -> anyhow::Result<()> {
|
|
for entry in fs::read_dir(path)? {
|
|
fs::remove_file(entry?.path())?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|