From 183cb87a9092c4898fdb135ec72b0c64f0350439 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 23 Dec 2024 14:04:23 -0500 Subject: [PATCH] Respect sources credentials in non-project workspaces --- crates/uv/src/commands/project/sync.rs | 35 +++++++++++ crates/uv/tests/it/lock.rs | 83 +++++++++++++++++++++++++- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/crates/uv/src/commands/project/sync.rs b/crates/uv/src/commands/project/sync.rs index f1e385dc7b26..935e7ddef2c5 100644 --- a/crates/uv/src/commands/project/sync.rs +++ b/crates/uv/src/commands/project/sync.rs @@ -526,6 +526,41 @@ fn apply_editable_mode(resolution: Resolution, editable: EditableMode) -> Resolu /// These credentials can come from any of `tool.uv.sources`, `tool.uv.dev-dependencies`, /// `project.dependencies`, and `project.optional-dependencies`. fn store_credentials_from_workspace(workspace: &Workspace) { + // Iterate over any sources in the workspace root. + for source in workspace.sources().values().flat_map(Sources::iter) { + match source { + Source::Git { git, .. } => { + uv_git::store_credentials_from_url(git); + } + Source::Url { url, .. } => { + uv_auth::store_credentials_from_url(url); + } + _ => {} + } + } + + // Iterate over any dependencies defined in the workspace root. + for requirement in workspace + .non_project_requirements() + .ok() + .into_iter() + .flatten() + { + let Some(VersionOrUrl::Url(url)) = &requirement.version_or_url else { + continue; + }; + match &url.parsed_url { + ParsedUrl::Git(ParsedGitUrl { url, .. }) => { + uv_git::store_credentials_from_url(url.repository()); + } + ParsedUrl::Archive(ParsedArchiveUrl { url, .. }) => { + uv_auth::store_credentials_from_url(url); + } + _ => {} + } + } + + // Iterate over each workspace member. for member in workspace.packages().values() { // Iterate over the `tool.uv.sources`. for source in member diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 97fce786f949..3fb70edbe572 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -7800,7 +7800,6 @@ fn lock_redact_https() -> Result<()> { Ok(()) } -/// However, we don't currently avoid persisting Git credentials in `uv.lock`. #[test] fn lock_redact_git_pep508() -> Result<()> { let context = TestContext::new("3.12").with_filtered_link_mode_warning(); @@ -7990,6 +7989,88 @@ fn lock_redact_git_sources() -> Result<()> { Ok(()) } +#[test] +fn lock_redact_git_pep508_non_project() -> Result<()> { + let context = TestContext::new("3.12").with_filtered_link_mode_warning(); + let token = decode_token(common::READ_ONLY_GITHUB_TOKEN); + + let filters: Vec<_> = [(token.as_str(), "***")] + .into_iter() + .chain(context.filters()) + .collect(); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str(&formatdoc! { + r#" + [tool.uv.workspace] + members = [] + + [dependency-groups] + dev = ["uv-private-pypackage @ git+https://{token}@github.com/astral-test/uv-private-pypackage"] + "#, + token = token, + })?; + + uv_snapshot!(&filters, context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: No `requires-python` value found in the workspace. Defaulting to `>=3.12`. + Resolved 1 package in [TIME] + "###); + + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => filters.clone(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [manifest] + requirements = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }] + + [[package]] + name = "uv-private-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-private-pypackage#d780faf0ac91257d4d5a4f0c5a0e4509608c0071" } + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(&filters, context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: No `requires-python` value found in the workspace. Defaulting to `>=3.12`. + Resolved 1 package in [TIME] + "###); + + // Install from the lockfile. + uv_snapshot!(&filters, context.sync().arg("--frozen").arg("--reinstall").arg("--no-cache"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + uv-private-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-private-pypackage@d780faf0ac91257d4d5a4f0c5a0e4509608c0071) + "###); + + Ok(()) +} + #[test] fn lock_redact_index_sources() -> Result<()> { let context = TestContext::new("3.12").with_filtered_link_mode_warning();