mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Move source distribution unpacking out of build
(#2294)
## Summary If a user provides a source distribution via a direct path, it can either be an archive (like a `.tar.gz` or `.zip` file) or a directory. If the former, we need to extract (e.g., unzip) the contents at some point. Previously, this extraction was in `uv-build`; this PR lifts it up to the distribution database. The first benefit here is that various methods that take the distribution are now simpler, as they can assume a directory. The second benefit is that we no longer extract _multiple times_ when working with a source distribution. (Previously, if we tried to get the metadata, then fell back and built the wheel, we'd extract the wheel _twice_.)
This commit is contained in:
parent
e321a2767d
commit
26f6919465
7 changed files with 107 additions and 47 deletions
|
@ -18,7 +18,6 @@ distribution-types = { path = "../distribution-types" }
|
|||
pep508_rs = { path = "../pep508-rs" }
|
||||
platform-host = { path = "../platform-host" }
|
||||
pypi-types = { path = "../pypi-types" }
|
||||
uv-extract = { path = "../uv-extract" }
|
||||
uv-fs = { path = "../uv-fs" }
|
||||
uv-interpreter = { path = "../uv-interpreter" }
|
||||
uv-traits = { path = "../uv-traits", features = ["serde"] }
|
||||
|
|
|
@ -62,10 +62,6 @@ static DEFAULT_BACKEND: Lazy<Pep517Backend> = Lazy::new(|| Pep517Backend {
|
|||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
IO(#[from] io::Error),
|
||||
#[error("Failed to extract archive: {0}")]
|
||||
Extraction(PathBuf, #[source] uv_extract::Error),
|
||||
#[error("Unsupported archive format (extension not recognized): {0}")]
|
||||
UnsupportedArchiveType(String),
|
||||
#[error("Invalid source distribution: {0}")]
|
||||
InvalidSourceDist(String),
|
||||
#[error("Invalid pyproject.toml")]
|
||||
|
@ -74,8 +70,6 @@ pub enum Error {
|
|||
EditableSetupPy,
|
||||
#[error("Failed to install requirements from {0}")]
|
||||
RequirementsInstall(&'static str, #[source] anyhow::Error),
|
||||
#[error("Source distribution not found at: {0}")]
|
||||
NotFound(PathBuf),
|
||||
#[error("Failed to create temporary virtualenv")]
|
||||
Virtualenv(#[from] uv_virtualenv::Error),
|
||||
#[error("Failed to run {0}")]
|
||||
|
@ -365,38 +359,10 @@ impl SourceBuild {
|
|||
) -> Result<Self, Error> {
|
||||
let temp_dir = tempdir_in(build_context.cache().root())?;
|
||||
|
||||
let metadata = match fs::metadata(source) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(err) if err.kind() == io::ErrorKind::NotFound => {
|
||||
return Err(Error::NotFound(source.to_path_buf()));
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
|
||||
let source_root = if metadata.is_dir() {
|
||||
source.to_path_buf()
|
||||
} else {
|
||||
debug!("Unpacking for build: {}", source.display());
|
||||
|
||||
let extracted = temp_dir.path().join("extracted");
|
||||
|
||||
// Unzip the archive into the temporary directory.
|
||||
let reader = fs_err::tokio::File::open(source).await?;
|
||||
uv_extract::stream::archive(tokio::io::BufReader::new(reader), source, &extracted)
|
||||
.await
|
||||
.map_err(|err| Error::Extraction(extracted.clone(), err))?;
|
||||
|
||||
// Extract the top-level directory from the archive.
|
||||
match uv_extract::strip_component(&extracted) {
|
||||
Ok(top_level) => top_level,
|
||||
Err(uv_extract::Error::NonSingularArchive(_)) => extracted,
|
||||
Err(err) => return Err(Error::Extraction(extracted.clone(), err)),
|
||||
}
|
||||
};
|
||||
let source_tree = if let Some(subdir) = subdirectory {
|
||||
source_root.join(subdir)
|
||||
source.join(subdir)
|
||||
} else {
|
||||
source_root
|
||||
source.to_path_buf()
|
||||
};
|
||||
|
||||
let default_backend: Pep517Backend = DEFAULT_BACKEND.clone();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue