Skip to content

Commit

Permalink
Add ResolvedDist instead of Dist::Installed
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb committed Mar 25, 2024
1 parent fdf9967 commit 4bd3f16
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 166 deletions.
13 changes: 2 additions & 11 deletions crates/distribution-types/src/cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use uv_normalize::PackageName;

use crate::direct_url::{DirectUrl, LocalFileUrl};
use crate::{
BuiltDist, Dist, DistributionMetadata, InstalledDist, InstalledMetadata, InstalledVersion,
Name, SourceDist, VersionOrUrl,
BuiltDist, Dist, DistributionMetadata, InstalledMetadata, InstalledVersion, Name, SourceDist,
VersionOrUrl,
};

/// A built distribution (wheel) that exists in the local cache.
Expand Down Expand Up @@ -39,15 +39,6 @@ impl CachedDist {
/// Initialize a [`CachedDist`] from a [`Dist`].
pub fn from_remote(remote: Dist, filename: WheelFilename, path: PathBuf) -> Self {
match remote {
Dist::Installed(InstalledDist::Registry(_dist)) => {
Self::Registry(CachedRegistryDist { filename, path })
}
Dist::Installed(InstalledDist::Url(dist)) => Self::Url(CachedDirectUrlDist {
filename,
url: VerbatimUrl::from_url(dist.url),
path,
editable: dist.editable,
}),
Dist::Built(BuiltDist::Registry(_dist)) => {
Self::Registry(CachedRegistryDist { filename, path })
}
Expand Down
9 changes: 8 additions & 1 deletion crates/distribution-types/src/installed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use pep440_rs::Version;
use uv_fs::Simplified;
use uv_normalize::PackageName;

use crate::{InstalledMetadata, InstalledVersion, Name};
use crate::{DistributionMetadata, InstalledMetadata, InstalledVersion, Name, VersionOrUrl};

/// A built distribution (wheel) that is installed in a virtual environment.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -114,6 +114,7 @@ impl InstalledDist {
pub fn metadata(&self) -> Result<pypi_types::Metadata23> {
let path = self.path().join("METADATA");
let contents = fs::read(&path)?;
// TODO(zanieb): Update this to use thiserror so we can unpack parse errors downstream
pypi_types::Metadata23::parse_metadata(&contents)
.with_context(|| format!("Failed to parse METADATA file at: {}", path.user_display()))
}
Expand Down Expand Up @@ -145,6 +146,12 @@ impl InstalledDist {
}
}

impl DistributionMetadata for InstalledDist {
fn version_or_url(&self) -> VersionOrUrl {
VersionOrUrl::Version(self.version())
}
}

impl Name for InstalledRegistryDist {
fn name(&self) -> &PackageName {
&self.name
Expand Down
11 changes: 2 additions & 9 deletions crates/distribution-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub use crate::index_url::*;
pub use crate::installed::*;
pub use crate::prioritized_distribution::*;
pub use crate::resolution::*;
pub use crate::resolved::*;
pub use crate::traits::*;

mod any;
Expand All @@ -70,6 +71,7 @@ mod index_url;
mod installed;
mod prioritized_distribution;
mod resolution;
mod resolved;
mod traits;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -121,7 +123,6 @@ impl std::fmt::Display for InstalledVersion<'_> {
/// The location can be index, url or path (wheel) or index, url, path or git (source distribution)
#[derive(Debug, Clone)]
pub enum Dist {
Installed(InstalledDist),
Built(BuiltDist),
Source(SourceDist),
}
Expand Down Expand Up @@ -365,15 +366,13 @@ impl Dist {
/// Returns the [`File`] instance, if this dist is from a registry with simple json api support
pub fn file(&self) -> Option<&File> {
match self {
Self::Installed(_) => None,
Self::Built(built) => built.file(),
Self::Source(source) => source.file(),
}
}

pub fn version(&self) -> Option<&Version> {
match self {
Self::Installed(installed) => Some(installed.version()),
Self::Built(wheel) => Some(wheel.version()),
Self::Source(source_dist) => source_dist.version(),
}
Expand Down Expand Up @@ -496,7 +495,6 @@ impl Name for BuiltDist {
impl Name for Dist {
fn name(&self) -> &PackageName {
match self {
Self::Installed(dist) => dist.name(),
Self::Built(dist) => dist.name(),
Self::Source(dist) => dist.name(),
}
Expand Down Expand Up @@ -569,7 +567,6 @@ impl DistributionMetadata for BuiltDist {
impl DistributionMetadata for Dist {
fn version_or_url(&self) -> VersionOrUrl {
match self {
Self::Installed(installed) => VersionOrUrl::Version(installed.version()),
Self::Built(dist) => dist.version_or_url(),
Self::Source(dist) => dist.version_or_url(),
}
Expand Down Expand Up @@ -732,15 +729,13 @@ impl RemoteSource for BuiltDist {
impl RemoteSource for Dist {
fn filename(&self) -> Result<Cow<'_, str>, Error> {
match self {
Self::Installed(_) => Ok(Cow::from("foo")),
Self::Built(dist) => dist.filename(),
Self::Source(dist) => dist.filename(),
}
}

fn size(&self) -> Option<u64> {
match self {
Self::Installed(_) => None,
Self::Built(dist) => dist.size(),
Self::Source(dist) => dist.size(),
}
Expand Down Expand Up @@ -964,15 +959,13 @@ impl Identifier for InstalledDist {
impl Identifier for Dist {
fn distribution_id(&self) -> DistributionId {
match self {
Self::Installed(dist) => dist.distribution_id(),
Self::Built(dist) => dist.distribution_id(),
Self::Source(dist) => dist.distribution_id(),
}
}

fn resource_id(&self) -> ResourceId {
match self {
Self::Installed(dist) => dist.resource_id(),
Self::Built(dist) => dist.resource_id(),
Self::Source(dist) => dist.resource_id(),
}
Expand Down
28 changes: 14 additions & 14 deletions crates/distribution-types/src/prioritized_distribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use pep440_rs::VersionSpecifiers;
use platform_tags::{IncompatibleTag, TagCompatibility, TagPriority};
use pypi_types::{Hashes, Yanked};

use crate::Dist;
use crate::{Dist, InstalledDist, ResolvedDistRef};

/// A collection of distributions that have been filtered by relevance.
#[derive(Debug, Default, Clone)]
Expand All @@ -25,7 +25,7 @@ struct PrioritizedDistInner {
#[derive(Debug, Clone)]
pub enum CompatibleDist<'a> {
/// The distribution is already installed and can be used.
InstalledDist(Dist),
InstalledDist(&'a InstalledDist),
/// The distribution should be resolved and installed using a source distribution.
SourceDist(&'a Dist),
/// The distribution should be resolved and installed using a wheel distribution.
Expand Down Expand Up @@ -286,29 +286,29 @@ impl PrioritizedDist {
}

impl<'a> CompatibleDist<'a> {
/// Return the [`Dist`] to use during resolution.
pub fn for_resolution(&self) -> &Dist {
/// Return the [`ResolvedDistRef`] to use during resolution.
pub fn for_resolution(&self) -> ResolvedDistRef<'a> {
match *self {
CompatibleDist::InstalledDist(ref dist) => dist,
CompatibleDist::SourceDist(sdist) => sdist,
CompatibleDist::CompatibleWheel(wheel, _) => wheel,
CompatibleDist::InstalledDist(dist) => ResolvedDistRef::Installed(dist),
CompatibleDist::SourceDist(sdist) => ResolvedDistRef::Installable(sdist),
CompatibleDist::CompatibleWheel(wheel, _) => ResolvedDistRef::Installable(wheel),
CompatibleDist::IncompatibleWheel {
source_dist: _,
wheel,
} => wheel,
} => ResolvedDistRef::Installable(wheel),
}
}

/// Return the [`Dist`] to use during installation.
pub fn for_installation(&self) -> &Dist {
/// Return the [`ResolvedDistRef`] to use during installation.
pub fn for_installation(&self) -> ResolvedDistRef<'a> {
match *self {
CompatibleDist::InstalledDist(ref dist) => dist,
CompatibleDist::SourceDist(sdist) => sdist,
CompatibleDist::CompatibleWheel(wheel, _) => wheel,
CompatibleDist::InstalledDist(dist) => ResolvedDistRef::Installed(dist),
CompatibleDist::SourceDist(sdist) => ResolvedDistRef::Installable(sdist),
CompatibleDist::CompatibleWheel(wheel, _) => ResolvedDistRef::Installable(wheel),
CompatibleDist::IncompatibleWheel {
source_dist,
wheel: _,
} => source_dist,
} => ResolvedDistRef::Installable(source_dist),
}
}
}
Expand Down
85 changes: 56 additions & 29 deletions crates/distribution-types/src/resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,46 @@ use rustc_hash::FxHashMap;
use pep508_rs::Requirement;
use uv_normalize::PackageName;

use crate::{BuiltDist, Dist, Name, PathSourceDist, SourceDist};
use crate::{BuiltDist, Dist, InstalledDist, Name, PathSourceDist, ResolvedDist, SourceDist};

/// A set of packages pinned at specific versions.
#[derive(Debug, Default, Clone)]
pub struct Resolution(FxHashMap<PackageName, Dist>);
pub struct Resolution(FxHashMap<PackageName, ResolvedDist>);

impl Resolution {
/// Create a new resolution from the given pinned packages.
pub fn new(packages: FxHashMap<PackageName, Dist>) -> Self {
pub fn new(packages: FxHashMap<PackageName, ResolvedDist>) -> Self {
Self(packages)
}

/// Return the distribution for the given package name, if it exists.
pub fn get(&self, package_name: &PackageName) -> Option<&Dist> {
pub fn get(&self, package_name: &PackageName) -> Option<&ResolvedDist> {
self.0.get(package_name)
}

/// Return the remote distribution for the given package name, if it exists.
pub fn get_remote(&self, package_name: &PackageName) -> Option<&Dist> {
match self.0.get(package_name) {
Some(dist) => match dist {
ResolvedDist::Installable(dist) => Some(dist),
ResolvedDist::Installed(_) => None,
},
None => None,
}
}

/// Iterate over the [`PackageName`] entities in this resolution.
pub fn packages(&self) -> impl Iterator<Item = &PackageName> {
self.0.keys()
}

/// Iterate over the [`Dist`] entities in this resolution.
pub fn distributions(&self) -> impl Iterator<Item = &Dist> {
/// Iterate over the [`ResolvedDist`] entities in this resolution.
pub fn distributions(&self) -> impl Iterator<Item = &ResolvedDist> {
self.0.values()
}

/// Iterate over the [`Dist`] entities in this resolution.
pub fn into_distributions(self) -> impl Iterator<Item = Dist> {
/// Iterate over the [`ResolvedDist`] entities in this resolution.
pub fn into_distributions(self) -> impl Iterator<Item = ResolvedDist> {
self.0.into_values()
}

Expand All @@ -48,17 +59,19 @@ impl Resolution {
/// Return the set of [`Requirement`]s that this resolution represents, exclusive of any
/// editable requirements.
pub fn requirements(&self) -> Vec<Requirement> {
let mut requirements = self
.0
.values()
.filter_map(|dist| match dist {
// Remove editable requirements
Dist::Source(SourceDist::Path(PathSourceDist { editable: true, .. })) => None,
// Remove already-installed distributions
Dist::Installed(_) => None,
dist => Some(Requirement::from(dist.clone())),
})
.collect::<Vec<_>>();
let mut requirements =
self.0
.values()
.filter_map(|dist| match dist {
// Remove editable requirements
&ResolvedDist::Installable(Dist::Source(SourceDist::Path(
PathSourceDist { editable: true, .. },
))) => None,
// Remove already-installed distributions
&ResolvedDist::Installed(_) => None,
dist => Some(Requirement::from(dist.clone())),
})
.collect::<Vec<_>>();
requirements.sort_unstable_by(|a, b| a.name.cmp(&b.name));
requirements
}
Expand All @@ -67,16 +80,6 @@ impl Resolution {
impl From<Dist> for Requirement {
fn from(dist: Dist) -> Self {
match dist {
Dist::Installed(dist) => Self {
name: dist.name().clone(),
extras: vec![],
version_or_url: Some(pep508_rs::VersionOrUrl::VersionSpecifier(
pep440_rs::VersionSpecifiers::from(
pep440_rs::VersionSpecifier::equals_version(dist.version().clone()),
),
)),
marker: None,
},
Dist::Built(BuiltDist::Registry(wheel)) => Self {
name: wheel.filename.name,
extras: vec![],
Expand Down Expand Up @@ -131,3 +134,27 @@ impl From<Dist> for Requirement {
}
}
}

impl From<InstalledDist> for Requirement {
fn from(dist: InstalledDist) -> Self {
Self {
name: dist.name().clone(),
extras: vec![],
version_or_url: Some(pep508_rs::VersionOrUrl::VersionSpecifier(
pep440_rs::VersionSpecifiers::from(pep440_rs::VersionSpecifier::equals_version(
dist.version().clone(),
)),
)),
marker: None,
}
}
}

impl From<ResolvedDist> for Requirement {
fn from(dist: ResolvedDist) -> Self {
match dist {
ResolvedDist::Installable(dist) => dist.clone().into(),
ResolvedDist::Installed(dist) => dist.clone().into(),
}
}
}
Loading

0 comments on commit 4bd3f16

Please sign in to comment.