diff --git a/crates/uv-build-frontend/src/lib.rs b/crates/uv-build-frontend/src/lib.rs index ee3bea5b89de..bc05676612ab 100644 --- a/crates/uv-build-frontend/src/lib.rs +++ b/crates/uv-build-frontend/src/lib.rs @@ -21,7 +21,7 @@ use std::rc::Rc; use std::str::FromStr; use std::sync::LazyLock; use std::{env, iter}; -use tempfile::{tempdir_in, TempDir}; +use tempfile::TempDir; use tokio::io::AsyncBufReadExt; use tokio::process::Command; use tokio::sync::{Mutex, Semaphore}; @@ -30,7 +30,7 @@ use tracing::{debug, info_span, instrument, Instrument}; use uv_configuration::{BuildKind, BuildOutput, ConfigSettings, LowerBound, SourceStrategy}; use uv_distribution::RequiresDist; use uv_distribution_types::{IndexLocations, Resolution}; -use uv_fs::{rename_with_retry, PythonExt, Simplified}; +use uv_fs::{PythonExt, Simplified}; use uv_pep440::Version; use uv_pep508::PackageName; use uv_pypi_types::{Requirement, VerbatimParsedUrl}; @@ -656,16 +656,7 @@ impl SourceBuild { pub async fn build(&self, wheel_dir: &Path) -> Result { // The build scripts run with the extracted root as cwd, so they need the absolute path. let wheel_dir = std::path::absolute(wheel_dir)?; - - // Prevent clashes from two uv processes building distributions in parallel. - let tmp_dir = tempdir_in(&wheel_dir)?; - let filename = self - .pep517_build(tmp_dir.path(), &self.pep517_backend) - .await?; - - let from = tmp_dir.path().join(&filename); - let to = wheel_dir.join(&filename); - rename_with_retry(from, to).await?; + let filename = self.pep517_build(&wheel_dir, &self.pep517_backend).await?; Ok(filename) } diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index 399e3eff4d0f..05ec66245ff2 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -1751,6 +1751,13 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { } } + // Build into a temporary directory, to prevent partial builds. + let build = self + .build_context + .cache() + .environment() + .map_err(Error::CacheWrite)?; + // Build the wheel. fs::create_dir_all(&cache_shard) .await @@ -1773,10 +1780,18 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { ) .await .map_err(Error::Build)? - .wheel(cache_shard) + .wheel(build.path()) .await .map_err(Error::Build)?; + // Move the wheel to the cache. + rename_with_retry( + build.path().join(&disk_filename), + cache_shard.join(&disk_filename), + ) + .await + .map_err(Error::CacheWrite)?; + // Read the metadata from the wheel. let filename = WheelFilename::from_str(&disk_filename)?; let metadata = read_wheel_metadata(&filename, &cache_shard.join(&disk_filename))?;