mirror of https://github.com/astral-sh/uv
120 lines
3.4 KiB
Rust
120 lines
3.4 KiB
Rust
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, GroupName, PackageName};
|
|
|
|
use crate::metadata::lowering::LoweringError;
|
|
pub use crate::metadata::requires_dist::{RequiresDist, DEV_DEPENDENCIES};
|
|
use crate::WorkspaceError;
|
|
|
|
mod lowering;
|
|
mod requires_dist;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum MetadataError {
|
|
#[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>,
|
|
pub dev_dependencies: BTreeMap<GroupName, Vec<pypi_types::Requirement>>,
|
|
}
|
|
|
|
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,
|
|
dev_dependencies: BTreeMap::default(),
|
|
}
|
|
}
|
|
|
|
/// 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, MetadataError> {
|
|
// Lower the requirements.
|
|
let RequiresDist {
|
|
name,
|
|
requires_dist,
|
|
provides_extras,
|
|
dev_dependencies,
|
|
} = RequiresDist::from_workspace(
|
|
pypi_types::RequiresDist {
|
|
name: metadata.name,
|
|
requires_dist: metadata.requires_dist,
|
|
provides_extras: metadata.provides_extras,
|
|
},
|
|
project_root,
|
|
preview_mode,
|
|
)
|
|
.await?;
|
|
|
|
// Combine with the remaining metadata.
|
|
Ok(Self {
|
|
name,
|
|
version: metadata.version,
|
|
requires_dist,
|
|
requires_python: metadata.requires_python,
|
|
provides_extras,
|
|
dev_dependencies,
|
|
})
|
|
}
|
|
}
|
|
|
|
/// 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![],
|
|
}
|
|
}
|
|
}
|