Refactor distribution types to adhere to a clear hierarchy (#369)

## Summary

This PR refactors our `RemoteDistribution` type such that it now follows
a clear hierarchy that matches the actual variants, and encodes the
differences between source and built distributions:

```rust
pub enum Distribution {
    Built(BuiltDistribution),
    Source(SourceDistribution),
}

pub enum BuiltDistribution {
    Registry(RegistryBuiltDistribution),
    DirectUrl(DirectUrlBuiltDistribution),
}

pub enum SourceDistribution {
    Registry(RegistrySourceDistribution),
    DirectUrl(DirectUrlSourceDistribution),
    Git(GitSourceDistribution),
}

/// A built distribution (wheel) that exists in a registry, like `PyPI`.
pub struct RegistryBuiltDistribution {
    pub name: PackageName,
    pub version: Version,
    pub file: File,
}

/// A built distribution (wheel) that exists at an arbitrary URL.
pub struct DirectUrlBuiltDistribution {
    pub name: PackageName,
    pub url: Url,
}

/// A source distribution that exists in a registry, like `PyPI`.
pub struct RegistrySourceDistribution {
    pub name: PackageName,
    pub version: Version,
    pub file: File,
}

/// A source distribution that exists at an arbitrary URL.
pub struct DirectUrlSourceDistribution {
    pub name: PackageName,
    pub url: Url,
}

/// A source distribution that exists in a Git repository.
pub struct GitSourceDistribution {
    pub name: PackageName,
    pub url: Url,
}
```

Most of the PR just stems downstream from this change. There are no
behavioral changes, so I'm largely relying on lint, tests, and the
compiler for correctness.
This commit is contained in:
Charlie Marsh 2023-11-09 18:45:41 -08:00 committed by GitHub
parent 33c0901a28
commit a148f9d0be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 1729 additions and 1098 deletions

View file

@ -6,6 +6,7 @@ use thiserror::Error;
use url::Url;
use pep508_rs::Requirement;
use puffin_distribution::{BuiltDistribution, SourceDistribution};
use puffin_normalize::PackageName;
use crate::pubgrub::{PubGrubPackage, PubGrubVersion};
@ -46,16 +47,32 @@ pub enum ResolveError {
#[error("Package `{0}` attempted to resolve via URL: {1}. URL dependencies must be expressed as direct requirements or constraints. Consider adding `{0} @ {1}` to your dependencies or constraints file.")]
DisallowedUrl(PackageName, Url),
#[error("Failed to build distribution: {filename}")]
RegistryDistribution {
#[error("Failed to fetch wheel metadata from: {filename}")]
RegistryBuiltDistribution {
filename: String,
// TODO(konstin): Gives this a proper error type
#[source]
err: anyhow::Error,
},
#[error("Failed to build distribution: {url}")]
UrlDistribution {
#[error("Failed to fetch wheel metadata from: {url}")]
UrlBuiltDistribution {
url: Url,
// TODO(konstin): Gives this a proper error type
#[source]
err: anyhow::Error,
},
#[error("Failed to build distribution: {filename}")]
RegistrySourceDistribution {
filename: String,
// TODO(konstin): Gives this a proper error type
#[source]
err: anyhow::Error,
},
#[error("Failed to build distribution from URL: {url}")]
UrlSourceDistribution {
url: Url,
// TODO(konstin): Gives this a proper error type
#[source]
@ -93,3 +110,35 @@ impl From<pubgrub::error::PubGrubError<PubGrubPackage, Range<PubGrubVersion>>> f
ResolveError::PubGrub(RichPubGrubError { source: value })
}
}
impl ResolveError {
pub fn from_source_distribution(distribution: SourceDistribution, err: anyhow::Error) -> Self {
match distribution {
SourceDistribution::Registry(sdist) => Self::RegistrySourceDistribution {
filename: sdist.file.filename.clone(),
err,
},
SourceDistribution::DirectUrl(sdist) => Self::UrlSourceDistribution {
url: sdist.url.clone(),
err,
},
SourceDistribution::Git(sdist) => Self::UrlSourceDistribution {
url: sdist.url.clone(),
err,
},
}
}
pub fn from_built_distribution(distribution: BuiltDistribution, err: anyhow::Error) -> Self {
match distribution {
BuiltDistribution::Registry(wheel) => Self::RegistryBuiltDistribution {
filename: wheel.file.filename.clone(),
err,
},
BuiltDistribution::DirectUrl(wheel) => Self::UrlBuiltDistribution {
url: wheel.url.clone(),
err,
},
}
}
}