Build source distributions at top-level of cache (#8905)

## Summary

See: https://github.com/astral-sh/uv/issues/8884. We build in a
directory that's deep within the cache; to help with file name length
limits, we should build at the top-level of the cache.
This commit is contained in:
Charlie Marsh 2024-11-07 19:20:24 -05:00 committed by GitHub
parent 705b6cd2a4
commit 8a1b581d07
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 13 deletions

View File

@ -21,7 +21,7 @@ use std::rc::Rc;
use std::str::FromStr; use std::str::FromStr;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::{env, iter}; use std::{env, iter};
use tempfile::{tempdir_in, TempDir}; use tempfile::TempDir;
use tokio::io::AsyncBufReadExt; use tokio::io::AsyncBufReadExt;
use tokio::process::Command; use tokio::process::Command;
use tokio::sync::{Mutex, Semaphore}; 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_configuration::{BuildKind, BuildOutput, ConfigSettings, LowerBound, SourceStrategy};
use uv_distribution::RequiresDist; use uv_distribution::RequiresDist;
use uv_distribution_types::{IndexLocations, Resolution}; 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_pep440::Version;
use uv_pep508::PackageName; use uv_pep508::PackageName;
use uv_pypi_types::{Requirement, VerbatimParsedUrl}; use uv_pypi_types::{Requirement, VerbatimParsedUrl};
@ -656,16 +656,7 @@ impl SourceBuild {
pub async fn build(&self, wheel_dir: &Path) -> Result<String, Error> { pub async fn build(&self, wheel_dir: &Path) -> Result<String, Error> {
// The build scripts run with the extracted root as cwd, so they need the absolute path. // The build scripts run with the extracted root as cwd, so they need the absolute path.
let wheel_dir = std::path::absolute(wheel_dir)?; let wheel_dir = std::path::absolute(wheel_dir)?;
let filename = self.pep517_build(&wheel_dir, &self.pep517_backend).await?;
// 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?;
Ok(filename) Ok(filename)
} }

View File

@ -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. // Build the wheel.
fs::create_dir_all(&cache_shard) fs::create_dir_all(&cache_shard)
.await .await
@ -1773,10 +1780,18 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
) )
.await .await
.map_err(Error::Build)? .map_err(Error::Build)?
.wheel(cache_shard) .wheel(build.path())
.await .await
.map_err(Error::Build)?; .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. // Read the metadata from the wheel.
let filename = WheelFilename::from_str(&disk_filename)?; let filename = WheelFilename::from_str(&disk_filename)?;
let metadata = read_wheel_metadata(&filename, &cache_shard.join(&disk_filename))?; let metadata = read_wheel_metadata(&filename, &cache_shard.join(&disk_filename))?;