From 86f6344b0f3d63c659de01d3c2131b4ddc2e0ffd Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 2 Sep 2025 15:01:59 -0500 Subject: [PATCH] fix(publish): Move `.crate` out of final artifact location When `target_dir == build_dir`, ensure `cargo publish` doesn't put intermediate artifacts in the final artifact location of `cargo package`. If anyone was relying on this behavior of `cargo publish`, it will break them. We could avoid this and instead consider the location change to be part of the opt-in of using `build-dir` (until we make it opt-out). Note that we expect to be able to change the layouf of content written to `build-dir` even if users aren't opting in. On the other hand, this will help identify people relying on intermediate artifacts. While there aren't any performance benefits to this, it consolidates all of the uplifting logic and avoids dealing with overlapping `target_dir` and `build_dir`. We could optimize this further by doing a `rename` and only doing a copy if that fails. --- src/cargo/ops/cargo_package/mod.rs | 37 ++++++++++------------------- tests/testsuite/build_dir.rs | 2 +- tests/testsuite/build_dir_legacy.rs | 2 +- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/cargo/ops/cargo_package/mod.rs b/src/cargo/ops/cargo_package/mod.rs index 9b24a29ef60..dd7e16bb644 100644 --- a/src/cargo/ops/cargo_package/mod.rs +++ b/src/cargo/ops/cargo_package/mod.rs @@ -163,11 +163,8 @@ fn create_package( let filename = pkg.package_id().tarball_name(); let build_dir = ws.build_dir(); paths::create_dir_all_excluded_from_backups_atomic(build_dir.as_path_unlocked())?; - let dir = build_dir.join("package"); - let mut dst = { - let tmp = format!(".{}", filename); - dir.open_rw_exclusive_create(&tmp, gctx, "package scratch space")? - }; + let dir = build_dir.join("package").join("tmp-crate"); + let dst = dir.open_rw_exclusive_create(&filename, gctx, "package scratch space")?; // Package up and test a temporary tarball and only move it to the final // location if it actually passes all our tests. Any previously existing @@ -179,14 +176,10 @@ fn create_package( let uncompressed_size = tar(ws, opts, pkg, local_reg, ar_files, dst.file(), &filename) .context("failed to prepare local package for uploading")?; - dst.seek(SeekFrom::Start(0))?; - let dst_path = dst.parent().join(&filename); - dst.rename(&dst_path)?; - let dst_metadata = dst .file() .metadata() - .with_context(|| format!("could not learn metadata for: `{}`", dst_path.display()))?; + .with_context(|| format!("could not learn metadata for: `{}`", dst.path().display()))?; let compressed_size = dst_metadata.len(); let uncompressed = HumanBytes(uncompressed_size); @@ -220,23 +213,17 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult