Skip to content

Commit

Permalink
Use canonical URLs in satisfaction check (#3373)
Browse files Browse the repository at this point in the history
## Summary

Closes #3367.
  • Loading branch information
charliermarsh committed May 4, 2024
1 parent 8adf5b1 commit 69e99b3
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 8 deletions.
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.

1 change: 1 addition & 0 deletions crates/uv-installer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ license = { workspace = true }
workspace = true

[dependencies]
cache-key = { workspace = true }
distribution-filename = { workspace = true }
distribution-types = { workspace = true }
install-wheel-rs = { workspace = true, default-features = false }
Expand Down
43 changes: 35 additions & 8 deletions crates/uv-installer/src/satisfies.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use anyhow::Result;
use cache_key::{CanonicalUrl, RepositoryUrl};
use std::fmt::Debug;
use tracing::log::debug;
use tracing::trace;

use distribution_types::{InstalledDirectUrlDist, InstalledDist, RequirementSource};
Expand Down Expand Up @@ -61,8 +63,12 @@ impl RequirementSatisfaction {
return Ok(Self::Mismatch);
}

if &requested_url.to_string() != installed_url
|| requested_subdirectory != installed_subdirectory
if requested_subdirectory != installed_subdirectory {
return Ok(Self::Mismatch);
}

if !CanonicalUrl::parse(installed_url)
.is_ok_and(|installed_url| installed_url == CanonicalUrl::new(requested_url))
{
return Ok(Self::Mismatch);
}
Expand Down Expand Up @@ -105,12 +111,30 @@ impl RequirementSatisfaction {
else {
return Ok(Self::Mismatch);
};
if &requested_repository.to_string() != installed_url
|| requested_subdirectory != installed_subdirectory
{

if requested_subdirectory != installed_subdirectory {
debug!(
"Subdirectory mismatch: {:?} vs. {:?}",
installed_subdirectory, requested_subdirectory
);
return Ok(Self::Mismatch);
}

if !RepositoryUrl::parse(installed_url).is_ok_and(|installed_url| {
installed_url == RepositoryUrl::new(requested_repository)
}) {
debug!(
"Repository mismatch: {:?} vs. {:?}",
installed_url, requested_repository
);
return Ok(Self::Mismatch);
}

if installed_reference.as_deref() != requested_reference.as_str() {
debug!(
"Reference mismatch: {:?} vs. {:?}",
installed_reference, requested_reference
);
return Ok(Self::OutOfDate);
}

Expand All @@ -136,9 +160,12 @@ impl RequirementSatisfaction {
return Ok(Self::Mismatch);
};

if &requested_url.to_string() != installed_url
|| requested_editable.unwrap_or_default()
!= installed_editable.unwrap_or_default()
if requested_editable != installed_editable {
return Ok(Self::Mismatch);
}

if !CanonicalUrl::parse(installed_url)
.is_ok_and(|installed_url| installed_url == CanonicalUrl::new(requested_url))
{
return Ok(Self::Mismatch);
}
Expand Down
25 changes: 25 additions & 0 deletions crates/uv/tests/pip_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4093,6 +4093,31 @@ fn already_installed_remote_url() {

context.assert_installed("uv_public_pypackage", "0.1.0");

// Request installation again with a different URL, but the same _canonical_ URL. We should
// resolve the package (since we installed a specific commit, but are now requesting the default
// branch), but not reinstall the package.
uv_snapshot!(context.filters(), context.install().arg("uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Audited 1 package in [TIME]
"###);

// Request installation again with a different URL, but the same _canonical_ URL and the same
// commit. We should neither resolve nor reinstall the package, since it's already installed
// at this precise commit.
uv_snapshot!(context.filters(), context.install().arg("uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Audited 1 package in [TIME]
"###);

// Request installation again with just the name
// We should just audit the URL package since it fulfills this requirement
uv_snapshot!(
Expand Down

0 comments on commit 69e99b3

Please sign in to comment.