From 335105ebc5e61202d2bae58b901cbab8f215a43b Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 27 Sep 2024 15:38:39 -0400 Subject: [PATCH] Pin named indexes --- crates/uv-workspace/src/pyproject.rs | 15 ++++++++++++++- crates/uv/src/commands/project/add.rs | 17 ++++++++++++++++- crates/uv/tests/edit.rs | 13 ++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index 00154534952d4..7f021ae8a8fe2 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -689,6 +689,7 @@ impl Source { source: RequirementSource, workspace: bool, editable: Option, + index: Option, rev: Option, tag: Option, branch: Option, @@ -729,7 +730,19 @@ impl Source { } let source = match source { - RequirementSource::Registry { .. } => return Ok(None), + RequirementSource::Registry { index: Some(_), .. } => { + return Ok(None); + } + RequirementSource::Registry { index: None, .. } => { + if let Some(index) = index { + Source::Registry { + index, + marker: MarkerTree::TRUE, + } + } else { + return Ok(None); + } + } RequirementSource::Path { install_path, .. } | RequirementSource::Directory { install_path, .. } => Source::Path { editable, diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index a53bca8dd8370..e1cf2b3763824 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -381,6 +381,13 @@ pub(crate) async fn add( } } + // If the user provides a single, named index, pin all requirements to that index. + let index = indexes + .first() + .as_ref() + .and_then(|index| index.name.as_ref()) + .filter(|_| indexes.len() == 1); + // Add the requirements to the `pyproject.toml` or script. let mut toml = match &target { Target::Script(script, _) => { @@ -426,6 +433,7 @@ pub(crate) async fn add( requirement, false, editable, + index.cloned(), rev.clone(), tag.clone(), branch.clone(), @@ -441,6 +449,7 @@ pub(crate) async fn add( requirement, workspace, editable, + index.cloned(), rev.clone(), tag.clone(), branch.clone(), @@ -709,7 +718,11 @@ async fn lock_and_sync( }; // Only set a minimum version for registry requirements. - if edit.source.is_some() { + if edit + .source + .as_ref() + .is_some_and(|source| !matches!(source, Source::Registry { .. })) + { continue; } @@ -900,6 +913,7 @@ fn resolve_requirement( requirement: pypi_types::Requirement, workspace: bool, editable: Option, + index: Option, rev: Option, tag: Option, branch: Option, @@ -910,6 +924,7 @@ fn resolve_requirement( requirement.source.clone(), workspace, editable, + index, rev, tag, branch, diff --git a/crates/uv/tests/edit.rs b/crates/uv/tests/edit.rs index 34a2889f2fed6..289b441986658 100644 --- a/crates/uv/tests/edit.rs +++ b/crates/uv/tests/edit.rs @@ -5064,7 +5064,7 @@ fn add_no_warn_index_url() -> Result<()> { /// Add an index provided via `--index`. #[test] -fn add_index_url() -> Result<()> { +fn add_index() -> Result<()> { let context = TestContext::new("3.12"); let pyproject_toml = context.temp_dir.child("pyproject.toml"); @@ -5149,6 +5149,7 @@ fn add_index_url() -> Result<()> { ----- stdout ----- ----- stderr ----- + warning: Missing version constraint (e.g., a lower bound) for `jinja2` Resolved 4 packages in [TIME] Prepared 2 packages in [TIME] Installed 2 packages in [TIME] @@ -5178,6 +5179,9 @@ fn add_index_url() -> Result<()> { [[tool.uv.index]] url = "https://pypi.org/simple" + + [tool.uv.sources] + jinja2 = { index = "pytorch" } "### ); }); @@ -5237,7 +5241,7 @@ fn add_index_url() -> Result<()> { [package.metadata] requires-dist = [ { name = "iniconfig", specifier = "==2.0.0" }, - { name = "jinja2", specifier = ">=3.1.3" }, + { name = "jinja2", specifier = ">=3.1.3", index = "https://download.pytorch.org/whl/cu121" }, ] "### ); @@ -5276,6 +5280,9 @@ fn add_index_url() -> Result<()> { [[tool.uv.index]] url = "https://pypi.org/simple" + + [tool.uv.sources] + jinja2 = { index = "pytorch" } "### ); }); @@ -5341,7 +5348,7 @@ fn add_index_url() -> Result<()> { [package.metadata] requires-dist = [ { name = "iniconfig", specifier = "==2.0.0" }, - { name = "jinja2", specifier = ">=3.1.3" }, + { name = "jinja2", specifier = ">=3.1.3", index = "https://test.pypi.org/simple" }, ] "### );