mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Normalize registry source URLs before validating lockfile
This commit is contained in:
parent
0458081567
commit
8fcffbb8b9
3 changed files with 101 additions and 2 deletions
|
@ -171,6 +171,17 @@ impl UrlString {
|
|||
.unwrap_or_else(|| self.0.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the [`UrlString`] with trailing slash removed.
|
||||
#[must_use]
|
||||
pub fn without_trailing_slash(&self) -> Self {
|
||||
Self(
|
||||
self.as_ref()
|
||||
.strip_suffix('/')
|
||||
.map(SmallString::from)
|
||||
.unwrap_or_else(|| self.0.clone()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for UrlString {
|
||||
|
|
|
@ -1478,9 +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))
|
||||
.is_some_and(|remotes| !remotes.contains(&url))
|
||||
{
|
||||
let name = &package.id.name;
|
||||
let version = &package
|
||||
|
@ -1793,7 +1795,7 @@ pub enum SatisfiesResult<'lock> {
|
|||
/// The lockfile is missing a workspace member.
|
||||
MissingRoot(PackageName),
|
||||
/// The lockfile referenced a remote index that was not provided
|
||||
MissingRemoteIndex(&'lock PackageName, &'lock Version, &'lock UrlString),
|
||||
MissingRemoteIndex(&'lock PackageName, &'lock Version, UrlString),
|
||||
/// The lockfile referenced a local index that was not provided
|
||||
MissingLocalIndex(&'lock PackageName, &'lock Version, &'lock Path),
|
||||
/// A package in the lockfile contains different `requires-dist` metadata than expected.
|
||||
|
|
|
@ -28366,3 +28366,89 @@ fn lock_with_inconsistent_trailing_slash() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Run `uv lock --locked` with a lockfile with trailing slashes on index URLs.
|
||||
#[test]
|
||||
fn lock_with_index_trailing_slashes_in_lockfile() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["anyio"]
|
||||
|
||||
[[tool.uv.index]]
|
||||
name = "pypi-proxy"
|
||||
url = "https://pypi-proxy.fly.dev/simple"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let lock = context.temp_dir.child("uv.lock");
|
||||
lock.write_str(r#"
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[options]
|
||||
exclude-newer = "2024-03-25T00:00:00Z"
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
source = { registry = "https://pypi-proxy.fly.dev/simple/" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "sniffio" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642, upload-time = "2024-02-19T08:36:28.641Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584, upload-time = "2024-02-19T08:36:26.842Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
source = { registry = "https://pypi-proxy.fly.dev/simple/" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426, upload-time = "2023-11-25T15:40:54.902Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567, upload-time = "2023-11-25T15:40:52.604Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "anyio" }]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi-proxy.fly.dev/simple/" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
||||
]
|
||||
"#
|
||||
)?;
|
||||
|
||||
// Run `uv lock --locked`.
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 4 packages in [TIME]
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue