Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't error on multiple matching index URLs #2627

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/distribution-types/src/index_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub enum IndexUrl {

impl IndexUrl {
/// Return the raw URL for the index.
pub(crate) fn url(&self) -> &Url {
pub fn url(&self) -> &Url {
match self {
Self::Pypi(url) => url.raw(),
Self::Url(url) => url.raw(),
Expand Down
1 change: 1 addition & 0 deletions crates/uv-requirements/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ authors.workspace = true
license.workspace = true

[dependencies]
cache-key = { workspace = true }
distribution-filename = { workspace = true }
distribution-types = { workspace = true }
pep508_rs = { workspace = true }
Expand Down
40 changes: 24 additions & 16 deletions crates/uv-requirements/src/specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use indexmap::IndexMap;
use rustc_hash::FxHashSet;
use tracing::{instrument, Level};

use crate::{ExtrasSpecification, RequirementsSource};
use cache_key::CanonicalUrl;
use distribution_types::{FlatIndexLocation, IndexUrl};
use pep508_rs::{Requirement, RequirementsTxtRequirement};
use requirements_txt::{EditableRequirement, FindLink, RequirementsTxt};
Expand All @@ -14,6 +14,8 @@ use uv_fs::Simplified;
use uv_normalize::{ExtraName, PackageName};
use uv_warnings::warn_user;

use crate::{ExtrasSpecification, RequirementsSource};

#[derive(Debug, Default)]
pub struct RequirementsSpecification {
/// The name of the project specifying requirements.
Expand Down Expand Up @@ -205,13 +207,15 @@ impl RequirementsSpecification {
spec.project = source.project;
}

if let Some(url) = source.index_url {
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs.` {url}",
));
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
}
spec.index_url = Some(url);
spec.index_url = Some(index_url);
}
spec.no_index |= source.no_index;
spec.extra_index_urls.extend(source.extra_index_urls);
Expand All @@ -236,13 +240,15 @@ impl RequirementsSpecification {
spec.constraints.extend(source.constraints);
spec.constraints.extend(source.overrides);

if let Some(url) = source.index_url {
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs.` {url}",
));
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
}
spec.index_url = Some(url);
spec.index_url = Some(index_url);
}
spec.no_index |= source.no_index;
spec.extra_index_urls.extend(source.extra_index_urls);
Expand All @@ -267,13 +273,15 @@ impl RequirementsSpecification {
spec.overrides.extend(source.constraints);
spec.overrides.extend(source.overrides);

if let Some(url) = source.index_url {
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs.` {url}",
));
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
}
spec.index_url = Some(url);
spec.index_url = Some(index_url);
}
spec.no_index |= source.no_index;
spec.extra_index_urls.extend(source.extra_index_urls);
Expand Down
32 changes: 30 additions & 2 deletions crates/uv/tests/pip_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3812,7 +3812,7 @@ fn index_url_requirements_txt() -> Result<()> {
Ok(())
}

/// Raise an error when multiple `requirements.txt` files include `--index-url` flags.
/// Raise an error when multiple `requirements.txt` files include different `--index-url` flags.
#[test]
fn conflicting_index_urls_requirements_txt() -> Result<()> {
let context = TestContext::new("3.12");
Expand All @@ -3831,7 +3831,35 @@ fn conflicting_index_urls_requirements_txt() -> Result<()> {
----- stdout -----

----- stderr -----
error: Multiple index URLs specified: `https://google.com/` vs.` https://wikipedia.org/
error: Multiple index URLs specified: `https://google.com/` vs. `https://wikipedia.org/`
"###
);

Ok(())
}

/// Doesn't raise an error when multiple `requirements.txt` files include matching `--index-url` flags.
#[test]
fn matching_index_urls_requirements_txt() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("--index-url https://pypi.org/simple")?;

let constraints_in = context.temp_dir.child("constraints.in");
constraints_in.write_str("--index-url https://pypi.org/simple")?;

uv_snapshot!(context.compile()
.arg("requirements.in")
.arg("--constraint")
.arg("constraints.in"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] --exclude-newer 2023-11-18T12:00:00Z requirements.in --constraint constraints.in

----- stderr -----
Resolved 0 packages in [TIME]
"###
);

Expand Down
Loading