diff --git a/FAQ.md b/FAQ.md index 7cf3657707..f09f23c247 100644 --- a/FAQ.md +++ b/FAQ.md @@ -201,19 +201,6 @@ as an ergonomic choice it does _not_ block committing if `cargo sqlx prepare` fa We're working on a way for the macros to save their data to the filesystem automatically which should be part of SQLx 0.7, so your pre-commit hook would then just need to stage the changed files. This can be enabled by creating a directory and setting the `SQLX_OFFLINE_DIR` environment variable to it before compiling. -Additionally, if you're not using Cargo or have a nonstandard setup, you may want to set the `SQLX_TMP` -variable in order to store temporary query files somewhere that isn't picked up by git. -These files should get cleaned up automatically, but they may not if there's a failure. For example: - -```shell -$ mkdir .sqlx -$ export SQLX_OFFLINE_DIR="./.sqlx"` -$ # Optional and only useful if using a nonstandard setup, ensures temp files won't get picked up by git on failure -$ mkdir ./my-custom-target/sqlx -$ export SQLX_TMP="./my-custom-target/sqlx-tmp" -$ cargo check -``` - However, this behaviour is not considered stable and it is still recommended to use `cargo sqlx prepare`. ---- diff --git a/sqlx-cli/src/prepare.rs b/sqlx-cli/src/prepare.rs index 71921fd086..7e35844a32 100644 --- a/sqlx-cli/src/prepare.rs +++ b/sqlx-cli/src/prepare.rs @@ -171,7 +171,6 @@ fn run_prepare_step(ctx: &PrepareCtx, cache_dir: &Path) -> anyhow::Result<()> { check_command .arg("check") .args(&ctx.cargo_args) - .env("SQLX_TMP", tmp_dir) .env("DATABASE_URL", &ctx.connect_opts.database_url) .env("SQLX_OFFLINE", "false") .env("SQLX_OFFLINE_DIR", cache_dir); diff --git a/sqlx-macros-core/Cargo.toml b/sqlx-macros-core/Cargo.toml index 48e8d26491..53fadd21c0 100644 --- a/sqlx-macros-core/Cargo.toml +++ b/sqlx-macros-core/Cargo.toml @@ -48,6 +48,7 @@ tokio = { workspace = true, optional = true } dotenvy = { workspace = true } +atomic-write-file = { version = "0.1" } hex = { version = "0.4.3" } heck = { version = "0.4", features = ["unicode"] } either = "1.6.1" diff --git a/sqlx-macros-core/src/query/data.rs b/sqlx-macros-core/src/query/data.rs index 273ccdd14d..70eb9c04e0 100644 --- a/sqlx-macros-core/src/query/data.rs +++ b/sqlx-macros-core/src/query/data.rs @@ -150,31 +150,22 @@ where } } - pub(super) fn save_in( - &self, - dir: impl AsRef, - tmp_dir: impl AsRef, - ) -> crate::Result<()> { - // Output to a temporary file first, then move it atomically to avoid clobbering - // other invocations trying to write to the same path. - - // Use a temp directory inside the workspace to avoid potential issues - // with persisting the file across filesystems. - let mut tmp_file = tempfile::NamedTempFile::new_in(tmp_dir) - .map_err(|err| format!("failed to create query file: {err:?}"))?; - - serde_json::to_writer_pretty(tmp_file.as_file_mut(), self) + pub(super) fn save_in(&self, dir: impl AsRef) -> crate::Result<()> { + let path = dir.as_ref().join(format!("query-{}.json", self.hash)); + let mut file = atomic_write_file::AtomicWriteFile::open(&path) + .map_err(|err| format!("failed to open the temporary file: {err:?}"))?; + + serde_json::to_writer_pretty(file.as_file_mut(), self) .map_err(|err| format!("failed to serialize query data to file: {err:?}"))?; - // Ensure there is a newline at the end of the JSON file to avoid accidental modification by IDE - // and make github diff tool happier - tmp_file - .as_file_mut() + + // Ensure there is a newline at the end of the JSON file to avoid + // accidental modification by IDE and make github diff tool happier. + file.as_file_mut() .write_all(b"\n") .map_err(|err| format!("failed to append a newline to file: {err:?}"))?; - tmp_file - .persist(dir.as_ref().join(format!("query-{}.json", self.hash))) - .map_err(|err| format!("failed to move query file: {err:?}"))?; + file.commit() + .map_err(|err| format!("failed to commit the query data to {path:?}: {err:?}"))?; Ok(()) } diff --git a/sqlx-macros-core/src/query/mod.rs b/sqlx-macros-core/src/query/mod.rs index 4b9ad30558..fe8fef3a0a 100644 --- a/sqlx-macros-core/src/query/mod.rs +++ b/sqlx-macros-core/src/query/mod.rs @@ -356,19 +356,6 @@ where if let Ok(dir) = env("SQLX_OFFLINE_DIR") { let path = PathBuf::from(&dir); - // Prefer SQLX_TMP if set explicitly. - // Otherwise fallback to CARGO_TARGET_DIR and then the standard target directory. - let tmp_dir = if let Ok(tmp_dir) = env("SQLX_TMP") { - PathBuf::from(tmp_dir) - } else if let Ok(target_dir) = env("CARGO_TARGET_DIR") { - PathBuf::from(target_dir) - } else { - let tmp_target = PathBuf::from("./target/sqlx"); - fs::create_dir_all(&tmp_target) - .map_err(|e| format!("Error creating cache directory: {e:?}"))?; - tmp_target - }; - match fs::metadata(&path) { Err(e) => { if e.kind() != io::ErrorKind::NotFound { @@ -387,7 +374,7 @@ where } // .sqlx exists and is a directory, store data. - data.save_in(path, tmp_dir)?; + data.save_in(path)?; } } }