mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
Support editable in pip-sync and pip-compile (#587)
Support `-e path/do/dir` in pip-sync and and pip-compile.
This commit is contained in:
parent
f62458f600
commit
f059c6e6a6
47 changed files with 1016 additions and 250 deletions
|
@ -1,5 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -13,9 +14,9 @@ use url::Url;
|
|||
|
||||
use distribution_filename::{WheelFilename, WheelFilenameError};
|
||||
use distribution_types::direct_url::DirectGitUrl;
|
||||
use distribution_types::{BuiltDist, Dist, Metadata, SourceDist};
|
||||
use distribution_types::{BuiltDist, Dist, LocalEditable, Metadata, SourceDist};
|
||||
use platform_tags::Tags;
|
||||
use puffin_cache::{Cache, CacheBucket, WheelCache};
|
||||
use puffin_cache::{digest, Cache, CacheBucket, WheelCache};
|
||||
use puffin_client::RegistryClient;
|
||||
use puffin_git::GitSource;
|
||||
use puffin_traits::BuildContext;
|
||||
|
@ -273,6 +274,26 @@ impl<'a, Context: BuildContext + Send + Sync> DistributionDatabase<'a, Context>
|
|||
}
|
||||
}
|
||||
|
||||
/// Build a directory into an editable wheel.
|
||||
pub async fn build_wheel_editable(
|
||||
&self,
|
||||
editable: &LocalEditable,
|
||||
editable_wheel_dir: &Path,
|
||||
) -> Result<(LocalWheel, Metadata21), DistributionDatabaseError> {
|
||||
let (dist, disk_filename, filename, metadata) = self
|
||||
.builder
|
||||
.build_editable(editable, editable_wheel_dir)
|
||||
.await?;
|
||||
|
||||
let built_wheel = BuiltWheel {
|
||||
dist,
|
||||
filename,
|
||||
path: editable_wheel_dir.join(disk_filename),
|
||||
target: editable_wheel_dir.join(digest(&editable.path)),
|
||||
};
|
||||
Ok((LocalWheel::Built(built_wheel), metadata))
|
||||
}
|
||||
|
||||
/// Given a remote source distribution, return a precise variant, if possible.
|
||||
///
|
||||
/// For example, given a Git dependency with a reference to a branch or tag, return a URL
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pub use distribution_database::{DistributionDatabase, DistributionDatabaseError};
|
||||
pub use download::{DiskWheel, InMemoryWheel, LocalWheel};
|
||||
pub use download::{BuiltWheel, DiskWheel, InMemoryWheel, LocalWheel};
|
||||
pub use index::{BuiltWheelIndex, RegistryWheelIndex};
|
||||
pub use reporter::Reporter;
|
||||
pub use source_dist::{SourceDistCachedBuilder, SourceDistError};
|
||||
|
|
|
@ -2,14 +2,14 @@ use std::sync::Arc;
|
|||
|
||||
use url::Url;
|
||||
|
||||
use distribution_types::SourceDist;
|
||||
use distribution_types::Metadata;
|
||||
|
||||
pub trait Reporter: Send + Sync {
|
||||
/// Callback to invoke when a source distribution build is kicked off.
|
||||
fn on_build_start(&self, dist: &SourceDist) -> usize;
|
||||
fn on_build_start(&self, dist: &dyn Metadata) -> usize;
|
||||
|
||||
/// Callback to invoke when a source distribution build is complete.
|
||||
fn on_build_complete(&self, dist: &SourceDist, id: usize);
|
||||
fn on_build_complete(&self, dist: &dyn Metadata, id: usize);
|
||||
|
||||
/// Callback to invoke when a repository checkout begins.
|
||||
fn on_checkout_start(&self, url: &Url, rev: &str) -> usize;
|
||||
|
|
|
@ -21,7 +21,9 @@ use zip::ZipArchive;
|
|||
|
||||
use distribution_filename::{WheelFilename, WheelFilenameError};
|
||||
use distribution_types::direct_url::{DirectArchiveUrl, DirectGitUrl};
|
||||
use distribution_types::{GitSourceDist, Metadata, PathSourceDist, RemoteSource, SourceDist};
|
||||
use distribution_types::{
|
||||
Dist, GitSourceDist, LocalEditable, Metadata, PathSourceDist, RemoteSource, SourceDist,
|
||||
};
|
||||
use install_wheel_rs::read_dist_info;
|
||||
use platform_tags::Tags;
|
||||
use puffin_cache::{
|
||||
|
@ -31,7 +33,7 @@ use puffin_client::{CachedClient, CachedClientError, DataWithCachePolicy};
|
|||
use puffin_fs::write_atomic;
|
||||
use puffin_git::{Fetch, GitSource};
|
||||
use puffin_normalize::PackageName;
|
||||
use puffin_traits::{BuildContext, SourceBuildTrait};
|
||||
use puffin_traits::{BuildContext, BuildKind, SourceBuildTrait};
|
||||
use pypi_types::Metadata21;
|
||||
|
||||
use crate::locks::LockedFile;
|
||||
|
@ -63,7 +65,7 @@ pub enum SourceDistError {
|
|||
|
||||
// Build error
|
||||
#[error("Failed to build: {0}")]
|
||||
Build(Box<SourceDist>, #[source] anyhow::Error),
|
||||
Build(String, #[source] anyhow::Error),
|
||||
#[error("Built wheel has an invalid filename")]
|
||||
WheelFilename(#[from] WheelFilenameError),
|
||||
#[error("Package metadata name `{metadata}` does not match given name `{given}`")]
|
||||
|
@ -688,12 +690,17 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
fs::create_dir_all(&cache_entry.dir).await?;
|
||||
let disk_filename = self
|
||||
.build_context
|
||||
.setup_build(source_dist, subdirectory, &dist.to_string())
|
||||
.setup_build(
|
||||
source_dist,
|
||||
subdirectory,
|
||||
&dist.to_string(),
|
||||
BuildKind::Wheel,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| SourceDistError::Build(Box::new(dist.clone()), err))?
|
||||
.map_err(|err| SourceDistError::Build(dist.to_string(), err))?
|
||||
.wheel(&cache_entry.dir)
|
||||
.await
|
||||
.map_err(|err| SourceDistError::Build(Box::new(dist.clone()), err))?;
|
||||
.map_err(|err| SourceDistError::Build(dist.to_string(), err))?;
|
||||
|
||||
// Read the metadata from the wheel.
|
||||
let filename = WheelFilename::from_str(&disk_filename)?;
|
||||
|
@ -703,6 +710,40 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
Ok((disk_filename, filename, metadata))
|
||||
}
|
||||
|
||||
/// Build a single directory into an editable wheel
|
||||
pub async fn build_editable(
|
||||
&self,
|
||||
editable: &LocalEditable,
|
||||
editable_wheel_dir: &Path,
|
||||
) -> Result<(Dist, String, WheelFilename, Metadata21), SourceDistError> {
|
||||
debug!("Building (editable) {editable}");
|
||||
let disk_filename = self
|
||||
.build_context
|
||||
.setup_build(
|
||||
&editable.path,
|
||||
None,
|
||||
&editable.to_string(),
|
||||
BuildKind::Editable,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| SourceDistError::Build(editable.to_string(), err))?
|
||||
.wheel(editable_wheel_dir)
|
||||
.await
|
||||
.map_err(|err| SourceDistError::Build(editable.to_string(), err))?;
|
||||
let filename = WheelFilename::from_str(&disk_filename)?;
|
||||
// We finally have the name of the package and can construct the dist
|
||||
let dist = Dist::Source(SourceDist::Path(PathSourceDist {
|
||||
name: filename.name.clone(),
|
||||
url: editable.url().clone(),
|
||||
path: editable.path.clone(),
|
||||
editable: true,
|
||||
}));
|
||||
let metadata = read_metadata(&filename, editable_wheel_dir.join(&disk_filename))?;
|
||||
|
||||
debug!("Finished building (editable): {dist}");
|
||||
Ok((dist, disk_filename, filename, metadata))
|
||||
}
|
||||
|
||||
/// Read an existing cache entry, if it exists and is up-to-date.
|
||||
async fn read_fresh_metadata(
|
||||
cache_entry: &CacheEntry,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue