Move metadata into its own file (#3939)

Move `Metadata`, `MetadataLoweringError` and `ArchiveMetadata` into
their own file `metadata.rs` in `uv-distribution`, moving it out from
`lib.rs`. No functional changes.
This commit is contained in:
konsti 2024-05-31 15:24:10 +02:00 committed by GitHub
parent 3c074142f5
commit 72b1642232
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 149 additions and 141 deletions

View file

@ -32,8 +32,9 @@ use uv_types::BuildContext;
use crate::archive::Archive;
use crate::locks::Locks;
use crate::metadata::{ArchiveMetadata, Metadata};
use crate::source::SourceDistributionBuilder;
use crate::{ArchiveMetadata, Error, LocalWheel, Metadata, Reporter};
use crate::{Error, LocalWheel, Reporter};
/// A cached high-level interface to convert distributions (a requirement resolved to a location)
/// to a wheel or wheel metadata.

View file

@ -3,7 +3,7 @@ use std::path::PathBuf;
use tokio::task::JoinError;
use zip::result::ZipError;
use crate::MetadataLoweringError;
use crate::metadata::MetadataLoweringError;
use distribution_filename::WheelFilenameError;
use pep440_rs::Version;
use pypi_types::HashDigest;

View file

@ -6,7 +6,8 @@ use pep508_rs::VerbatimUrl;
use pypi_types::HashDigest;
use uv_cache::{Cache, CacheBucket, CacheEntry};
use crate::{Archive, HttpArchivePointer, LocalArchivePointer};
use crate::archive::Archive;
use crate::{HttpArchivePointer, LocalArchivePointer};
#[derive(Debug, Clone)]
pub struct CachedWheel {

View file

@ -1,20 +1,11 @@
use std::collections::BTreeMap;
use std::path::Path;
use thiserror::Error;
use archive::Archive;
pub use distribution_database::{DistributionDatabase, HttpArchivePointer, LocalArchivePointer};
pub use download::LocalWheel;
pub use error::Error;
pub use git::{git_url_to_precise, is_same_reference};
pub use index::{BuiltWheelIndex, RegistryWheelIndex};
use pep440_rs::{Version, VersionSpecifiers};
use pypi_types::{HashDigest, Metadata23};
pub use metadata::{ArchiveMetadata, Metadata};
pub use reporter::Reporter;
use requirement_lowering::{lower_requirement, LoweringError};
use uv_configuration::PreviewMode;
use uv_normalize::{ExtraName, PackageName};
use requirement_lowering::LoweringError;
pub use workspace::{ProjectWorkspace, Workspace, WorkspaceError, WorkspaceMember};
mod archive;
@ -24,133 +15,9 @@ mod error;
mod git;
mod index;
mod locks;
mod metadata;
pub mod pyproject;
mod reporter;
mod requirement_lowering;
mod source;
mod workspace;
#[derive(Debug, Error)]
pub enum MetadataLoweringError {
#[error(transparent)]
Workspace(#[from] WorkspaceError),
#[error("Failed to parse entry for: `{0}`")]
LoweringError(PackageName, #[source] LoweringError),
}
#[derive(Debug, Clone)]
pub struct Metadata {
// Mandatory fields
pub name: PackageName,
pub version: Version,
// Optional fields
pub requires_dist: Vec<pypi_types::Requirement>,
pub requires_python: Option<VersionSpecifiers>,
pub provides_extras: Vec<ExtraName>,
}
impl Metadata {
/// Lower without considering `tool.uv` in `pyproject.toml`, used for index and other archive
/// dependencies.
pub fn from_metadata23(metadata: Metadata23) -> Self {
Self {
name: metadata.name,
version: metadata.version,
requires_dist: metadata
.requires_dist
.into_iter()
.map(pypi_types::Requirement::from)
.collect(),
requires_python: metadata.requires_python,
provides_extras: metadata.provides_extras,
}
}
/// Lower by considering `tool.uv` in `pyproject.toml` if present, used for Git and directory
/// dependencies.
pub async fn from_workspace(
metadata: Metadata23,
project_root: &Path,
preview_mode: PreviewMode,
) -> Result<Self, MetadataLoweringError> {
// TODO(konsti): Limit discovery for Git checkouts to Git root.
// TODO(konsti): Cache workspace discovery.
let Some(project_workspace) =
ProjectWorkspace::from_maybe_project_root(project_root, None).await?
else {
return Ok(Self::from_metadata23(metadata));
};
Self::from_project_workspace(metadata, &project_workspace, preview_mode)
}
pub fn from_project_workspace(
metadata: Metadata23,
project_workspace: &ProjectWorkspace,
preview_mode: PreviewMode,
) -> Result<Metadata, MetadataLoweringError> {
let empty = BTreeMap::default();
let sources = project_workspace
.current_project()
.pyproject_toml()
.tool
.as_ref()
.and_then(|tool| tool.uv.as_ref())
.and_then(|uv| uv.sources.as_ref())
.unwrap_or(&empty);
let requires_dist = metadata
.requires_dist
.into_iter()
.map(|requirement| {
let requirement_name = requirement.name.clone();
lower_requirement(
requirement,
&metadata.name,
project_workspace.project_root(),
sources,
project_workspace.workspace(),
preview_mode,
)
.map_err(|err| MetadataLoweringError::LoweringError(requirement_name.clone(), err))
})
.collect::<Result<_, _>>()?;
Ok(Self {
name: metadata.name,
version: metadata.version,
requires_dist,
requires_python: metadata.requires_python,
provides_extras: metadata.provides_extras,
})
}
}
/// The metadata associated with an archive.
#[derive(Debug, Clone)]
pub struct ArchiveMetadata {
/// The [`Metadata`] for the underlying distribution.
pub metadata: Metadata,
/// The hashes of the source or built archive.
pub hashes: Vec<HashDigest>,
}
impl ArchiveMetadata {
/// Lower without considering `tool.uv` in `pyproject.toml`, used for index and other archive
/// dependencies.
pub fn from_metadata23(metadata: Metadata23) -> Self {
Self {
metadata: Metadata::from_metadata23(metadata),
hashes: vec![],
}
}
}
impl From<Metadata> for ArchiveMetadata {
fn from(metadata: Metadata) -> Self {
Self {
metadata,
hashes: vec![],
}
}
}

View file

@ -0,0 +1,137 @@
use std::collections::BTreeMap;
use std::path::Path;
use thiserror::Error;
use pep440_rs::{Version, VersionSpecifiers};
use pypi_types::{HashDigest, Metadata23};
use uv_configuration::PreviewMode;
use uv_normalize::{ExtraName, PackageName};
use crate::requirement_lowering::{lower_requirement, LoweringError};
use crate::{ProjectWorkspace, WorkspaceError};
#[derive(Debug, Error)]
pub enum MetadataLoweringError {
#[error(transparent)]
Workspace(#[from] WorkspaceError),
#[error("Failed to parse entry for: `{0}`")]
LoweringError(PackageName, #[source] LoweringError),
}
#[derive(Debug, Clone)]
pub struct Metadata {
// Mandatory fields
pub name: PackageName,
pub version: Version,
// Optional fields
pub requires_dist: Vec<pypi_types::Requirement>,
pub requires_python: Option<VersionSpecifiers>,
pub provides_extras: Vec<ExtraName>,
}
impl Metadata {
/// Lower without considering `tool.uv` in `pyproject.toml`, used for index and other archive
/// dependencies.
pub fn from_metadata23(metadata: Metadata23) -> Self {
Self {
name: metadata.name,
version: metadata.version,
requires_dist: metadata
.requires_dist
.into_iter()
.map(pypi_types::Requirement::from)
.collect(),
requires_python: metadata.requires_python,
provides_extras: metadata.provides_extras,
}
}
/// Lower by considering `tool.uv` in `pyproject.toml` if present, used for Git and directory
/// dependencies.
pub async fn from_workspace(
metadata: Metadata23,
project_root: &Path,
preview_mode: PreviewMode,
) -> Result<Self, MetadataLoweringError> {
// TODO(konsti): Limit discovery for Git checkouts to Git root.
// TODO(konsti): Cache workspace discovery.
let Some(project_workspace) =
ProjectWorkspace::from_maybe_project_root(project_root, None).await?
else {
return Ok(Self::from_metadata23(metadata));
};
Self::from_project_workspace(metadata, &project_workspace, preview_mode)
}
pub fn from_project_workspace(
metadata: Metadata23,
project_workspace: &ProjectWorkspace,
preview_mode: PreviewMode,
) -> Result<Metadata, MetadataLoweringError> {
let empty = BTreeMap::default();
let sources = project_workspace
.current_project()
.pyproject_toml()
.tool
.as_ref()
.and_then(|tool| tool.uv.as_ref())
.and_then(|uv| uv.sources.as_ref())
.unwrap_or(&empty);
let requires_dist = metadata
.requires_dist
.into_iter()
.map(|requirement| {
let requirement_name = requirement.name.clone();
lower_requirement(
requirement,
&metadata.name,
project_workspace.project_root(),
sources,
project_workspace.workspace(),
preview_mode,
)
.map_err(|err| MetadataLoweringError::LoweringError(requirement_name.clone(), err))
})
.collect::<Result<_, _>>()?;
Ok(Self {
name: metadata.name,
version: metadata.version,
requires_dist,
requires_python: metadata.requires_python,
provides_extras: metadata.provides_extras,
})
}
}
/// The metadata associated with an archive.
#[derive(Debug, Clone)]
pub struct ArchiveMetadata {
/// The [`Metadata`] for the underlying distribution.
pub metadata: Metadata,
/// The hashes of the source or built archive.
pub hashes: Vec<HashDigest>,
}
impl ArchiveMetadata {
/// Lower without considering `tool.uv` in `pyproject.toml`, used for index and other archive
/// dependencies.
pub fn from_metadata23(metadata: Metadata23) -> Self {
Self {
metadata: Metadata::from_metadata23(metadata),
hashes: vec![],
}
}
}
impl From<Metadata> for ArchiveMetadata {
fn from(metadata: Metadata) -> Self {
Self {
metadata,
hashes: vec![],
}
}
}

View file

@ -252,8 +252,9 @@ mod test {
use uv_configuration::PreviewMode;
use uv_normalize::PackageName;
use crate::metadata::Metadata;
use crate::pyproject::PyProjectToml;
use crate::{Metadata, ProjectWorkspace};
use crate::ProjectWorkspace;
async fn metadata_from_pyproject_toml(contents: &str) -> anyhow::Result<Metadata> {
let pyproject_toml: PyProjectToml = toml::from_str(contents)?;

View file

@ -37,9 +37,10 @@ use uv_types::{BuildContext, SourceBuildTrait};
use crate::distribution_database::ManagedClient;
use crate::error::Error;
use crate::git::{fetch_git_archive, resolve_precise};
use crate::metadata::{ArchiveMetadata, Metadata};
use crate::source::built_wheel_metadata::BuiltWheelMetadata;
use crate::source::revision::Revision;
use crate::{ArchiveMetadata, Metadata, Reporter};
use crate::Reporter;
mod built_wheel_metadata;
mod revision;