Skip to content

Commit

Permalink
Strip SHA when constructing package source (astral-sh#6097)
Browse files Browse the repository at this point in the history
## Summary

Similar to astral-sh#5805, but applies the normalization earlier so that
`--locked` passes for URLs that contain fragments.
  • Loading branch information
charliermarsh authored Aug 15, 2024
1 parent e3f345c commit 7b67b5a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 124 deletions.
8 changes: 7 additions & 1 deletion crates/distribution-types/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,18 @@ impl UrlString {
}

/// Return the [`UrlString`] with any query parameters and fragments removed.
pub fn base(&self) -> &str {
pub fn base_str(&self) -> &str {
self.as_ref()
.split_once(['#', '?'])
.map(|(path, _)| path)
.unwrap_or(self.as_ref())
}

/// Return the [`UrlString`] with any query parameters and fragments removed.
#[must_use]
pub fn as_base_url(&self) -> Self {
Self(self.base_str().to_string())
}
}

impl AsRef<str> for UrlString {
Expand Down
2 changes: 1 addition & 1 deletion crates/distribution-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ impl RemoteSource for UrlString {
fn filename(&self) -> Result<Cow<'_, str>, Error> {
// Take the last segment, stripping any query or fragment.
let last = self
.base()
.base_str()
.split('/')
.last()
.ok_or_else(|| Error::MissingPathSegments(self.to_string()))?;
Expand Down
32 changes: 20 additions & 12 deletions crates/uv-resolver/src/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2119,10 +2119,7 @@ impl SourceDist {
return Ok(None);
}

let url = reg_dist
.file
.url
.to_url_string()
let url = normalize_file_location(&reg_dist.file.url)
.map_err(LockErrorKind::InvalidFileUrl)
.map_err(LockError::from)?;
let hash = reg_dist.file.hashes.iter().max().cloned().map(Hash::from);
Expand All @@ -2147,7 +2144,7 @@ impl SourceDist {
return Err(kind.into());
};
Ok(SourceDist::Url {
url: UrlString::from(direct_dist.url.to_url()),
url: normalize_url(direct_dist.url.to_url()),
metadata: SourceDistMetadata {
hash: Some(hash),
size: None,
Expand Down Expand Up @@ -2177,7 +2174,7 @@ impl SourceDist {
let mut table = InlineTable::new();
match &self {
SourceDist::Url { url, .. } => {
table.insert("url", Value::from(url.base()));
table.insert("url", Value::from(url.as_ref()));
}
SourceDist::Path { path, .. } => {
table.insert("path", Value::from(PortablePath::from(path).to_string()));
Expand Down Expand Up @@ -2377,10 +2374,7 @@ impl Wheel {

fn from_registry_wheel(wheel: &RegistryBuiltWheel) -> Result<Wheel, LockError> {
let filename = wheel.filename.clone();
let url = wheel
.file
.url
.to_url_string()
let url = normalize_file_location(&wheel.file.url)
.map_err(LockErrorKind::InvalidFileUrl)
.map_err(LockError::from)?;
let hash = wheel.file.hashes.iter().max().cloned().map(Hash::from);
Expand All @@ -2396,7 +2390,7 @@ impl Wheel {
fn from_direct_dist(direct_dist: &DirectUrlBuiltDist, hashes: &[HashDigest]) -> Wheel {
Wheel {
url: WheelWireSource::Url {
url: direct_dist.url.to_url().into(),
url: normalize_url(direct_dist.url.to_url()),
},
hash: hashes.iter().max().cloned().map(Hash::from),
size: None,
Expand Down Expand Up @@ -2489,7 +2483,7 @@ impl Wheel {
let mut table = InlineTable::new();
match &self.url {
WheelWireSource::Url { url } => {
table.insert("url", Value::from(url.base()));
table.insert("url", Value::from(url.as_ref()));
}
WheelWireSource::Filename { filename } => {
table.insert("filename", Value::from(filename.to_string()));
Expand Down Expand Up @@ -2670,6 +2664,20 @@ impl<'de> serde::Deserialize<'de> for Hash {
}
}

/// Convert a [`FileLocation`] into a normalized [`UrlString`].
fn normalize_file_location(location: &FileLocation) -> Result<UrlString, ToUrlError> {
match location {
FileLocation::AbsoluteUrl(ref absolute) => Ok(absolute.as_base_url()),
_ => Ok(normalize_url(location.to_url()?)),
}
}

/// Convert a [`Url`] into a normalized [`UrlString`].
fn normalize_url(mut url: Url) -> UrlString {
url.set_fragment(None);
UrlString::from(url)
}

/// Normalize a [`Requirement`], which could come from a lockfile, a `pyproject.toml`, etc.
///
/// Performs the following steps:
Expand Down
Loading

0 comments on commit 7b67b5a

Please sign in to comment.