From 8cc523db6b17b243003c4bfe82913a98c3fed6e5 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 | 36 +++++++++--------------------- tests/testsuite/build_dir.rs | 2 +- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/cargo/ops/cargo_package/mod.rs b/src/cargo/ops/cargo_package/mod.rs index bbd94bb8b4a..2a46d4af324 100644 --- a/src/cargo/ops/cargo_package/mod.rs +++ b/src/cargo/ops/cargo_package/mod.rs @@ -160,11 +160,8 @@ fn create_package( } let filename = pkg.package_id().tarball_name(); - let dir = ws.build_dir().join("package"); - let mut dst = { - let tmp = format!(".{}", filename); - dir.open_rw_exclusive_create(&tmp, gctx, "package scratch space")? - }; + let dir = ws.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 @@ -176,14 +173,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); @@ -217,22 +210,15 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult