mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-15 02:07:51 +00:00
Load credentials for explicit members when lowering (#15844)
## Summary If the target for `uv pip compile` is a `pyproject.toml` in a subdirectory, we won't have loaded the credentials when we go to lower (since it won't be loaded as part of "configuration discovery"). We now add those indexes just-in-time. Closes https://github.com/astral-sh/uv/issues/15362.
This commit is contained in:
parent
43c187dd93
commit
ef17e7d0f4
4 changed files with 85 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -5624,6 +5624,7 @@ dependencies = [
|
|||
"toml",
|
||||
"tracing",
|
||||
"url",
|
||||
"uv-auth",
|
||||
"uv-cache",
|
||||
"uv-cache-info",
|
||||
"uv-client",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ doctest = false
|
|||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
uv-auth = { workspace = true }
|
||||
uv-cache = { workspace = true }
|
||||
uv-cache-info = { workspace = true }
|
||||
uv-client = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use either::Either;
|
||||
use thiserror::Error;
|
||||
|
|
@ -222,20 +223,20 @@ impl LoweredRequirement {
|
|||
.find(|Index { name, .. }| {
|
||||
name.as_ref().is_some_and(|name| *name == index)
|
||||
})
|
||||
.map(
|
||||
|Index {
|
||||
url, format: kind, ..
|
||||
}| IndexMetadata {
|
||||
url: url.clone(),
|
||||
format: *kind,
|
||||
},
|
||||
)
|
||||
else {
|
||||
return Err(LoweringError::MissingIndex(
|
||||
requirement.name.clone(),
|
||||
index,
|
||||
));
|
||||
};
|
||||
if let Some(credentials) = index.credentials() {
|
||||
let credentials = Arc::new(credentials);
|
||||
uv_auth::store_credentials(index.raw_url(), credentials);
|
||||
}
|
||||
let index = IndexMetadata {
|
||||
url: index.url.clone(),
|
||||
format: index.format,
|
||||
};
|
||||
let conflict = project_name.and_then(|project_name| {
|
||||
if let Some(extra) = extra {
|
||||
Some(ConflictItem::from((project_name.clone(), extra)))
|
||||
|
|
@ -456,20 +457,20 @@ impl LoweredRequirement {
|
|||
.find(|Index { name, .. }| {
|
||||
name.as_ref().is_some_and(|name| *name == index)
|
||||
})
|
||||
.map(
|
||||
|Index {
|
||||
url, format: kind, ..
|
||||
}| IndexMetadata {
|
||||
url: url.clone(),
|
||||
format: *kind,
|
||||
},
|
||||
)
|
||||
else {
|
||||
return Err(LoweringError::MissingIndex(
|
||||
requirement.name.clone(),
|
||||
index,
|
||||
));
|
||||
};
|
||||
if let Some(credentials) = index.credentials() {
|
||||
let credentials = Arc::new(credentials);
|
||||
uv_auth::store_credentials(index.raw_url(), credentials);
|
||||
}
|
||||
let index = IndexMetadata {
|
||||
url: index.url.clone(),
|
||||
format: index.format,
|
||||
};
|
||||
let conflict = None;
|
||||
let source = registry_source(&requirement, index, conflict);
|
||||
(source, marker)
|
||||
|
|
|
|||
|
|
@ -17784,3 +17784,69 @@ fn omit_python_patch_universal() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn credentials_from_subdirectory() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Create a local dependency in a subdirectory.
|
||||
let pyproject_toml = context.temp_dir.child("foo").child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "1.0.0"
|
||||
dependencies = ["iniconfig"]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.uv.sources]
|
||||
iniconfig = { index = "internal" }
|
||||
|
||||
[[tool.uv.index]]
|
||||
name = "internal"
|
||||
url = "https://pypi-proxy.fly.dev/basic-auth/simple/"
|
||||
explicit = true
|
||||
"#,
|
||||
)?;
|
||||
context
|
||||
.temp_dir
|
||||
.child("foo")
|
||||
.child("src")
|
||||
.child("foo")
|
||||
.child("__init__.py")
|
||||
.touch()?;
|
||||
|
||||
uv_snapshot!(context.filters(), context
|
||||
.pip_compile()
|
||||
.arg("foo/pyproject.toml"), @r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because iniconfig was not found in the package registry and foo depends on iniconfig, we can conclude that your requirements are unsatisfiable.
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context
|
||||
.pip_compile()
|
||||
.arg("foo/pyproject.toml")
|
||||
.env("UV_INDEX_INTERNAL_USERNAME", "public")
|
||||
.env("UV_INDEX_INTERNAL_PASSWORD", "heron"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] foo/pyproject.toml
|
||||
iniconfig==2.0.0
|
||||
# via foo (foo/pyproject.toml)
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue