mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-17 13:58:29 +00:00
Read cached registry distributions when --config-settings
are present (#10578)
## Summary Closes https://github.com/astral-sh/uv/issues/10577.
This commit is contained in:
parent
53d3d5e3b8
commit
b6aa40b29d
3 changed files with 104 additions and 6 deletions
|
@ -3,6 +3,8 @@ use std::collections::hash_map::Entry;
|
|||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use uv_cache::{Cache, CacheBucket, WheelCache};
|
||||
use uv_cache_key::cache_digest;
|
||||
use uv_configuration::ConfigSettings;
|
||||
use uv_distribution_types::{CachedRegistryDist, Hashed, Index, IndexLocations, IndexUrl};
|
||||
use uv_fs::{directories, files, symlinks};
|
||||
use uv_normalize::PackageName;
|
||||
|
@ -31,6 +33,7 @@ pub struct RegistryWheelIndex<'a> {
|
|||
index_locations: &'a IndexLocations,
|
||||
hasher: &'a HashStrategy,
|
||||
index: FxHashMap<&'a PackageName, Vec<IndexEntry<'a>>>,
|
||||
build_configuration: &'a ConfigSettings,
|
||||
}
|
||||
|
||||
impl<'a> RegistryWheelIndex<'a> {
|
||||
|
@ -40,12 +43,14 @@ impl<'a> RegistryWheelIndex<'a> {
|
|||
tags: &'a Tags,
|
||||
index_locations: &'a IndexLocations,
|
||||
hasher: &'a HashStrategy,
|
||||
build_configuration: &'a ConfigSettings,
|
||||
) -> Self {
|
||||
Self {
|
||||
cache,
|
||||
tags,
|
||||
index_locations,
|
||||
hasher,
|
||||
build_configuration,
|
||||
index: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +72,7 @@ impl<'a> RegistryWheelIndex<'a> {
|
|||
self.tags,
|
||||
self.index_locations,
|
||||
self.hasher,
|
||||
self.build_configuration,
|
||||
)),
|
||||
};
|
||||
versions
|
||||
|
@ -79,6 +85,7 @@ impl<'a> RegistryWheelIndex<'a> {
|
|||
tags: &Tags,
|
||||
index_locations: &'index IndexLocations,
|
||||
hasher: &HashStrategy,
|
||||
build_configuration: &ConfigSettings,
|
||||
) -> Vec<IndexEntry<'index>> {
|
||||
let mut entries = vec![];
|
||||
|
||||
|
@ -162,9 +169,8 @@ impl<'a> RegistryWheelIndex<'a> {
|
|||
WheelCache::Index(index.url()).wheel_dir(package.to_string()),
|
||||
);
|
||||
|
||||
// For registry wheels, the cache structure is: `<index>/<package-name>/<version>/`.
|
||||
// For registry source distributions, the cache structure is: `<index>/<package-name>/<version>/`.
|
||||
for shard in directories(&cache_shard) {
|
||||
// Read the existing metadata from the cache, if it exists.
|
||||
let cache_shard = cache_shard.shard(shard);
|
||||
|
||||
// Read the revision from the cache.
|
||||
|
@ -190,7 +196,16 @@ impl<'a> RegistryWheelIndex<'a> {
|
|||
};
|
||||
|
||||
if let Some(revision) = revision {
|
||||
for wheel_dir in symlinks(cache_shard.join(revision.id())) {
|
||||
let cache_shard = cache_shard.shard(revision.id());
|
||||
|
||||
// If there are build settings, we need to scope to a cache shard.
|
||||
let cache_shard = if build_configuration.is_empty() {
|
||||
cache_shard
|
||||
} else {
|
||||
cache_shard.shard(cache_digest(build_configuration))
|
||||
};
|
||||
|
||||
for wheel_dir in symlinks(cache_shard) {
|
||||
if let Some(wheel) = CachedWheel::from_built_source(wheel_dir) {
|
||||
if wheel.filename.compatibility(tags).is_compatible() {
|
||||
// Enforce hash-checking based on the source distribution.
|
||||
|
|
|
@ -56,7 +56,8 @@ impl<'a> Planner<'a> {
|
|||
tags: &Tags,
|
||||
) -> Result<Plan> {
|
||||
// Index all the already-downloaded wheels in the cache.
|
||||
let mut registry_index = RegistryWheelIndex::new(cache, tags, index_locations, hasher);
|
||||
let mut registry_index =
|
||||
RegistryWheelIndex::new(cache, tags, index_locations, hasher, config_settings);
|
||||
let built_index = BuiltWheelIndex::new(cache, tags, hasher, config_settings);
|
||||
|
||||
let mut cached = vec![];
|
||||
|
@ -248,7 +249,7 @@ impl<'a> Planner<'a> {
|
|||
}
|
||||
Some(&entry.dist)
|
||||
}) {
|
||||
debug!("Requirement already cached: {distribution}");
|
||||
debug!("Registry requirement already cached: {distribution}");
|
||||
cached.push(CachedDist::Registry(distribution.clone()));
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -3251,7 +3251,89 @@ fn launcher_with_symlink() -> Result<()> {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn config_settings() {
|
||||
fn config_settings_registry() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Install with a `-C` flag. In this case, the flag has no impact on the build, but uv should
|
||||
// respect it anyway.
|
||||
uv_snapshot!(context.filters(), context.pip_install()
|
||||
.arg("iniconfig")
|
||||
.arg("--no-binary")
|
||||
.arg("iniconfig")
|
||||
.arg("-C=global-option=build_ext"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
"###
|
||||
);
|
||||
|
||||
// Uninstall the package.
|
||||
uv_snapshot!(context.filters(), context.pip_uninstall()
|
||||
.arg("iniconfig"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Uninstalled 1 package in [TIME]
|
||||
- iniconfig==2.0.0
|
||||
"###);
|
||||
|
||||
// Re-install the package, with the same flag. We should read from the cache.
|
||||
uv_snapshot!(context.filters(), context.pip_install()
|
||||
.arg("iniconfig")
|
||||
.arg("--no-binary")
|
||||
.arg("iniconfig")
|
||||
.arg("-C=global-option=build_ext"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
"###
|
||||
);
|
||||
|
||||
// Uninstall the package.
|
||||
uv_snapshot!(context.filters(), context.pip_uninstall()
|
||||
.arg("iniconfig"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Uninstalled 1 package in [TIME]
|
||||
- iniconfig==2.0.0
|
||||
"###);
|
||||
|
||||
// Re-install the package, without the flag. We should build it from source.
|
||||
uv_snapshot!(context.filters(), context.pip_install()
|
||||
.arg("iniconfig")
|
||||
.arg("--no-binary")
|
||||
.arg("iniconfig"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn config_settings_path() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Install the editable package.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue