Skip to content

Commit

Permalink
Make registry hashes optional in the lockfile
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jul 17, 2024
1 parent f74235b commit 1446b30
Showing 1 changed file with 47 additions and 39 deletions.
86 changes: 47 additions & 39 deletions crates/uv-resolver/src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, VecDeque};
use std::fmt::{Debug, Display};
use std::iter;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::Arc;
Expand Down Expand Up @@ -308,15 +307,16 @@ impl Lock {

// Also check that our sources are consistent with whether we have
// hashes or not.
let requires_hash = dist.id.source.requires_hash();
for wheel in &dist.wheels {
if requires_hash != wheel.hash.is_some() {
return Err(LockErrorKind::Hash {
id: dist.id.clone(),
artifact_type: "wheel",
expected: requires_hash,
if let Some(requires_hash) = dist.id.source.requires_hash() {
for wheel in &dist.wheels {
if requires_hash != wheel.hash.is_some() {
return Err(LockErrorKind::Hash {
id: dist.id.clone(),
artifact_type: "wheel",
expected: requires_hash,
}
.into());
}
.into());
}
}
}
Expand Down Expand Up @@ -794,7 +794,10 @@ impl Distribution {
let file = Box::new(distribution_types::File {
dist_info_metadata: false,
filename: filename.to_string(),
hashes: vec![sdist.hash().0.clone()],
hashes: sdist
.hash()
.map(|hash| vec![hash.0.clone()])
.unwrap_or_default(),
requires_python: None,
size: sdist.size(),
upload_time_utc_ms: None,
Expand Down Expand Up @@ -833,8 +836,11 @@ impl Distribution {
{
// When resolving from a lockfile all sources are equally compatible.
let compat = SourceDistCompatibility::Compatible(HashComparison::Matched);
let hash = self.sdist.as_ref().unwrap().hash().0.clone();
prioritized_dist.insert_source(sdist, iter::once(hash), compat);
let hash = self
.sdist
.as_ref()
.and_then(|sdist| sdist.hash().map(|h| h.0.clone()));
prioritized_dist.insert_source(sdist, hash, compat);
};

// Add any wheels.
Expand Down Expand Up @@ -1026,7 +1032,9 @@ impl Distribution {
fn hashes(&self) -> Vec<HashDigest> {
let mut hashes = Vec::new();
if let Some(ref sdist) = self.sdist {
hashes.push(sdist.hash().0.clone());
if let Some(hash) = sdist.hash() {
hashes.push(hash.0.clone());
}
}
for wheel in &self.wheels {
hashes.extend(wheel.hash.as_ref().map(|h| h.0.clone()));
Expand Down Expand Up @@ -1430,14 +1438,18 @@ impl Source {
}
}

/// Returns true when this source kind requires a hash.
/// Returns `Some(true)` to indicate that the source kind _must_ include a
/// hash.
///
/// Returns `Some(false)` to indicate that the source kind _must not_
/// include a hash.
///
/// When this returns false, it also implies that a hash should
/// _not_ be present.
fn requires_hash(&self) -> bool {
/// Returns `None` to indicate that the source kind _may_ include a hash.
fn requires_hash(&self) -> Option<bool> {
match *self {
Self::Registry(..) | Self::Direct(..) | Self::Path(..) => true,
Self::Git(..) | Self::Directory(..) | Self::Editable(..) => false,
Self::Registry(..) => None,
Self::Direct(..) | Self::Path(..) => Some(true),
Self::Git(..) | Self::Directory(..) | Self::Editable(..) => Some(false),
}
}
}
Expand Down Expand Up @@ -1572,7 +1584,7 @@ enum GitSourceKind {
#[derive(Clone, Debug, serde::Deserialize, PartialEq, Eq)]
struct SourceDistMetadata {
/// A hash of the source distribution.
hash: Hash,
hash: Option<Hash>,
/// The size of the source distribution in bytes.
///
/// This is only present for source distributions that come from registries.
Expand Down Expand Up @@ -1629,12 +1641,13 @@ impl SourceDist {
}
}

fn hash(&self) -> &Hash {
fn hash(&self) -> Option<&Hash> {
match &self {
SourceDist::Url { metadata, .. } => &metadata.hash,
SourceDist::Path { metadata, .. } => &metadata.hash,
SourceDist::Url { metadata, .. } => metadata.hash.as_ref(),
SourceDist::Path { metadata, .. } => metadata.hash.as_ref(),
}
}

fn size(&self) -> Option<u64> {
match &self {
SourceDist::Url { metadata, .. } => metadata.size,
Expand All @@ -1655,7 +1668,9 @@ impl SourceDist {
table.insert("path", Value::from(serialize_path_with_dot(path).as_ref()));
}
}
table.insert("hash", Value::from(self.hash().to_string()));
if let Some(hash) = self.hash() {
table.insert("hash", Value::from(hash.to_string()));
}
if let Some(size) = self.size() {
table.insert("size", Value::from(i64::try_from(size)?));
}
Expand Down Expand Up @@ -1686,7 +1701,7 @@ impl SourceDist {
let Some(sdist) = built_dist.sdist.as_ref() else {
return Ok(None);
};
SourceDist::from_registry_dist(id, sdist).map(Some)
SourceDist::from_registry_dist(sdist).map(Some)
}
Dist::Built(_) => Ok(None),
Dist::Source(ref source_dist) => SourceDist::from_source_dist(id, source_dist, hashes),
Expand All @@ -1700,7 +1715,7 @@ impl SourceDist {
) -> Result<Option<SourceDist>, LockError> {
match *source_dist {
distribution_types::SourceDist::Registry(ref reg_dist) => {
SourceDist::from_registry_dist(id, reg_dist).map(Some)
SourceDist::from_registry_dist(reg_dist).map(Some)
}
distribution_types::SourceDist::DirectUrl(ref direct_dist) => {
SourceDist::from_direct_dist(id, direct_dist, hashes).map(Some)
Expand All @@ -1714,24 +1729,14 @@ impl SourceDist {
}
}

fn from_registry_dist(
id: &DistributionId,
reg_dist: &RegistrySourceDist,
) -> Result<SourceDist, LockError> {
fn from_registry_dist(reg_dist: &RegistrySourceDist) -> Result<SourceDist, LockError> {
let url = reg_dist
.file
.url
.to_url()
.map_err(LockErrorKind::InvalidFileUrl)
.map_err(LockError::from)?;
let Some(hash) = reg_dist.file.hashes.first().cloned().map(Hash::from) else {
let kind = LockErrorKind::Hash {
id: id.clone(),
artifact_type: "registry source distribution",
expected: true,
};
return Err(kind.into());
};
let hash = reg_dist.file.hashes.first().cloned().map(Hash::from);
let size = reg_dist.file.size;
Ok(SourceDist::Url {
url,
Expand All @@ -1754,7 +1759,10 @@ impl SourceDist {
};
Ok(SourceDist::Url {
url: direct_dist.url.to_url(),
metadata: SourceDistMetadata { hash, size: None },
metadata: SourceDistMetadata {
hash: Some(hash),
size: None,
},
})
}
}
Expand Down

0 comments on commit 1446b30

Please sign in to comment.