diff --git a/crates/uv-distribution-types/src/file.rs b/crates/uv-distribution-types/src/file.rs index a75af3977..89da7b87e 100644 --- a/crates/uv-distribution-types/src/file.rs +++ b/crates/uv-distribution-types/src/file.rs @@ -169,26 +169,6 @@ impl UrlString { .map(|(path, _)| Cow::Owned(UrlString(SmallString::from(path)))) .unwrap_or(Cow::Borrowed(self)) } - - /// Return the [`UrlString`] (as a [`Cow`]) with trailing slash removed. - /// - /// This matches the semantics of [`Url::pop_if_empty`], which will not trim a trailing slash if - /// it's the only path segment, e.g., `https://example.com/` would be unchanged. - #[must_use] - pub fn without_trailing_slash(&self) -> Cow<'_, Self> { - self.as_ref() - .strip_suffix('/') - .filter(|path| { - // Only strip the trailing slash if there's _another_ trailing slash that isn't a - // part of the scheme. - path.split_once("://") - .map(|(_scheme, rest)| rest) - .unwrap_or(path) - .contains('/') - }) - .map(|path| Cow::Owned(UrlString(SmallString::from(path)))) - .unwrap_or(Cow::Borrowed(self)) - } } impl AsRef for UrlString { @@ -283,38 +263,4 @@ mod tests { ); assert!(matches!(url.without_fragment(), Cow::Owned(_))); } - - #[test] - fn without_trailing_slash() { - // Borrows a URL without a slash - let url = UrlString("https://example.com/path".into()); - assert_eq!(&*url.without_trailing_slash(), &url); - assert!(matches!(url.without_trailing_slash(), Cow::Borrowed(_))); - - // Removes the trailing slash if present on the URL - let url = UrlString("https://example.com/path/".into()); - assert_eq!( - &*url.without_trailing_slash(), - &UrlString("https://example.com/path".into()) - ); - assert!(matches!(url.without_trailing_slash(), Cow::Owned(_))); - - // Does not remove a trailing slash if it's the only path segment - let url = UrlString("https://example.com/".into()); - assert_eq!(&*url.without_trailing_slash(), &url); - assert!(matches!(url.without_trailing_slash(), Cow::Borrowed(_))); - - // Does not remove a trailing slash if it's the only path segment with a missing scheme - let url = UrlString("example.com/".into()); - assert_eq!(&*url.without_trailing_slash(), &url); - assert!(matches!(url.without_trailing_slash(), Cow::Borrowed(_))); - - // Removes the trailing slash when the scheme is missing - let url = UrlString("example.com/path/".into()); - assert_eq!( - &*url.without_trailing_slash(), - &UrlString("example.com/path".into()) - ); - assert!(matches!(url.without_trailing_slash(), Cow::Owned(_))); - } } diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index 14e2ed258..92fc24cd5 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -1455,7 +1455,7 @@ impl Lock { Some(path) } }) - .collect::>() + .collect::>() }); // Add the workspace packages to the queue. @@ -1478,12 +1478,11 @@ impl Lock { if let Source::Registry(index) = &package.id.source { match index { RegistrySource::Url(url) => { - // Normalize URL before validating. - let url = url.without_trailing_slash(); - if remotes - .as_ref() - .is_some_and(|remotes| !remotes.contains(&url)) - { + if remotes.as_ref().is_some_and(|remotes| { + !remotes.iter().any(|remote| { + matches!(url.as_ref().strip_prefix(remote.as_ref()), Some("" | "/")) + }) + }) { let name = &package.id.name; let version = &package .id @@ -1493,7 +1492,7 @@ impl Lock { return Ok(SatisfiesResult::MissingRemoteIndex( name, version, - url.into_owned(), + url.clone(), )); } }