Fix credential caching for index roots when URL ends in simple/ (#11336)

Closes https://github.com/astral-sh/uv/issues/11244

See test failure at
https://github.com/astral-sh/uv/pull/11336/commits/e12f98a3e40ddb61edd2fd32be4bfcf01c160102
This commit is contained in:
Zanie Blue
2025-02-08 09:23:31 -06:00
committed by GitHub
parent 07d3e5085a
commit 6dfac4559b
2 changed files with 54 additions and 3 deletions
+8 -3
View File
@@ -160,14 +160,19 @@ impl Index {
/// For indexes with a `/simple` endpoint, this is simply the URL with the final segment
/// removed. This is useful, e.g., for credential propagation to other endpoints on the index.
pub fn root_url(&self) -> Option<Url> {
let segments = self.raw_url().path_segments()?;
let last = segments.last()?;
let mut segments = self.raw_url().path_segments()?;
let last = match segments.next_back()? {
// If the last segment is empty due to a trailing `/`, skip it (as in `pop_if_empty`)
"" => segments.next_back()?,
segment => segment,
};
if !last.eq_ignore_ascii_case("simple") {
return None;
}
let mut url = self.raw_url().clone();
url.path_segments_mut().ok()?.pop();
url.path_segments_mut().ok()?.pop_if_empty().pop();
Some(url)
}
+46
View File
@@ -8358,6 +8358,52 @@ fn lock_multiple_indexes_same_realm_different_credentials() -> Result<()> {
Ok(())
}
// Same as [`lock_multiple_indexes_same_realm_different_credentials`], but with trailing slashes
// on the index URL
#[test]
fn lock_multiple_indexes_same_realm_different_credentials_trailing_slash() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["iniconfig", "anyio"]
[tool.uv.sources]
iniconfig = { index = "internal-proxy-heron" }
anyio = { index = "internal-proxy-eagle" }
[[tool.uv.index]]
name = "internal-proxy-heron"
url = "https://pypi-proxy.fly.dev/basic-auth-heron/simple/"
[[tool.uv.index]]
name = "internal-proxy-eagle"
url = "https://pypi-proxy.fly.dev/basic-auth-eagle/simple/"
"#,
)?;
// Provide credentials via environment variables.
uv_snapshot!(context.filters(), context.lock()
.env(EnvVars::index_username("INTERNAL_PROXY_HERON"), "public")
.env(EnvVars::index_password("INTERNAL_PROXY_HERON"), "heron")
.env(EnvVars::index_username("INTERNAL_PROXY_EAGLE"), "public")
.env(EnvVars::index_password("INTERNAL_PROXY_EAGLE"), "eagle"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 5 packages in [TIME]
"###);
Ok(())
}
/// Resolve against an index that uses relative links.
#[test]
fn lock_relative_index() -> Result<()> {