Remove some dependencies on EditableRequirement (#3727)
## Summary Use `LocalEditable` instead throughout the `ResolvedEditable` pipeline.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
use serde::Deserialize;
|
||||
use std::path::Path;
|
||||
|
||||
use distribution_types::{
|
||||
CachedDist, InstalledDist, InstalledMetadata, InstalledVersion, LocalEditable, Name,
|
||||
};
|
||||
use pypi_types::Metadata23;
|
||||
use requirements_txt::EditableRequirement;
|
||||
|
||||
use uv_normalize::PackageName;
|
||||
|
||||
@@ -112,10 +112,10 @@ impl std::fmt::Display for ResolvedEditable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the [`EditableRequirement`] contains dynamic metadata.
|
||||
pub fn is_dynamic(editable: &EditableRequirement) -> bool {
|
||||
/// Returns `true` if the source tree at the given path contains dynamic metadata.
|
||||
pub fn is_dynamic(path: &Path) -> bool {
|
||||
// If there's no `pyproject.toml`, we assume it's dynamic.
|
||||
let Ok(contents) = fs_err::read_to_string(editable.path.join("pyproject.toml")) else {
|
||||
let Ok(contents) = fs_err::read_to_string(path.join("pyproject.toml")) else {
|
||||
return true;
|
||||
};
|
||||
let Ok(pyproject_toml) = toml::from_str::<PyProjectToml>(&contents) else {
|
||||
|
||||
@@ -322,7 +322,7 @@ impl SitePackages {
|
||||
}
|
||||
|
||||
// Does the editable have dynamic metadata?
|
||||
if is_dynamic(requirement) {
|
||||
if is_dynamic(&requirement.path) {
|
||||
return Ok(SatisfiesResult::Unsatisfied(requirement.to_string()));
|
||||
}
|
||||
|
||||
|
||||
@@ -342,7 +342,9 @@ pub(crate) async fn pip_install(
|
||||
// Build all editable distributions. The editables are shared between resolution and
|
||||
// installation, and should live for the duration of the command.
|
||||
let editables = ResolvedEditables::resolve(
|
||||
editables,
|
||||
editables
|
||||
.into_iter()
|
||||
.map(ResolvedEditables::from_requirement),
|
||||
&site_packages,
|
||||
&reinstall,
|
||||
&hasher,
|
||||
|
||||
@@ -297,7 +297,9 @@ pub(crate) async fn pip_sync(
|
||||
|
||||
// Resolve any editables.
|
||||
let editables = ResolvedEditables::resolve(
|
||||
editables,
|
||||
editables
|
||||
.into_iter()
|
||||
.map(ResolvedEditables::from_requirement),
|
||||
&site_packages,
|
||||
reinstall,
|
||||
&hasher,
|
||||
|
||||
@@ -108,7 +108,10 @@ pub(crate) async fn lock(
|
||||
// Build all editable distributions. The editables are shared between resolution and
|
||||
// installation, and should live for the duration of the command.
|
||||
let editables = ResolvedEditables::resolve(
|
||||
spec.editables.clone(),
|
||||
spec.editables
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(ResolvedEditables::from_requirement),
|
||||
&EmptyInstalledPackages,
|
||||
&reinstall,
|
||||
&hasher,
|
||||
|
||||
@@ -574,7 +574,10 @@ pub(crate) async fn update_environment(
|
||||
// Build all editable distributions. The editables are shared between resolution and
|
||||
// installation, and should live for the duration of the command.
|
||||
let editables = ResolvedEditables::resolve(
|
||||
spec.editables.clone(),
|
||||
spec.editables
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(ResolvedEditables::from_requirement),
|
||||
&site_packages,
|
||||
&reinstall,
|
||||
&hasher,
|
||||
|
||||
+16
-27
@@ -46,7 +46,7 @@ impl ResolvedEditables {
|
||||
/// Resolve the set of editables that need to be installed.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn resolve(
|
||||
editables: Vec<EditableRequirement>,
|
||||
editables: impl IntoIterator<Item = LocalEditable>,
|
||||
installed_packages: &impl InstalledPackagesProvider,
|
||||
reinstall: &Reinstall,
|
||||
hasher: &HashStrategy,
|
||||
@@ -59,8 +59,8 @@ impl ResolvedEditables {
|
||||
printer: Printer,
|
||||
) -> Result<Self> {
|
||||
// Partition the editables into those that are already installed, and those that must be built.
|
||||
let mut installed = Vec::with_capacity(editables.len());
|
||||
let mut builds = Vec::with_capacity(editables.len());
|
||||
let mut installed = Vec::new();
|
||||
let mut builds = Vec::new();
|
||||
for editable in editables {
|
||||
match reinstall {
|
||||
Reinstall::None => {
|
||||
@@ -107,20 +107,7 @@ impl ResolvedEditables {
|
||||
)
|
||||
.with_reporter(DownloadReporter::from(printer).with_length(builds.len() as u64));
|
||||
|
||||
let editables = LocalEditables::from_editables(builds.iter().map(|editable| {
|
||||
let EditableRequirement {
|
||||
url,
|
||||
path,
|
||||
extras,
|
||||
marker: _,
|
||||
origin: _,
|
||||
} = editable;
|
||||
LocalEditable {
|
||||
url: url.clone(),
|
||||
path: path.clone(),
|
||||
extras: extras.clone(),
|
||||
}
|
||||
}));
|
||||
let editables = LocalEditables::from_editables(builds.into_iter());
|
||||
|
||||
let temp_dir = tempfile::tempdir_in(cache.root())?;
|
||||
|
||||
@@ -193,21 +180,27 @@ impl ResolvedEditables {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Convert an [`EditableRequirement`] into a [`LocalEditable`].
|
||||
pub(crate) fn from_requirement(editable: EditableRequirement) -> LocalEditable {
|
||||
LocalEditable {
|
||||
url: editable.url,
|
||||
path: editable.path,
|
||||
extras: editable.extras,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [`InstalledEditable`] if the installed distribution is up-to-date for the given
|
||||
/// requirement.
|
||||
fn up_to_date(
|
||||
editable: &EditableRequirement,
|
||||
dist: &InstalledDist,
|
||||
) -> Result<Option<InstalledEditable>> {
|
||||
fn up_to_date(editable: &LocalEditable, dist: &InstalledDist) -> Result<Option<InstalledEditable>> {
|
||||
// If the editable isn't up-to-date, don't reuse it.
|
||||
if !ArchiveTimestamp::up_to_date_with(&editable.path, ArchiveTarget::Install(dist))? {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
// If the editable is dynamic, don't reuse it.
|
||||
if is_dynamic(editable) {
|
||||
if is_dynamic(&editable.path) {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
@@ -217,11 +210,7 @@ fn up_to_date(
|
||||
};
|
||||
|
||||
Ok(Some(InstalledEditable {
|
||||
editable: LocalEditable {
|
||||
url: editable.url.clone(),
|
||||
path: editable.path.clone(),
|
||||
extras: editable.extras.clone(),
|
||||
},
|
||||
editable: editable.clone(),
|
||||
wheel: (*dist).clone(),
|
||||
metadata,
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user