mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Always store registry index on resolution packages (#11815)
## Summary Closes https://github.com/astral-sh/uv/issues/11776.
This commit is contained in:
parent
fb35875f24
commit
7f4269ed08
4 changed files with 231 additions and 50 deletions
|
@ -541,27 +541,48 @@ impl ResolverOutput {
|
|||
|
||||
// 3. Look for hashes from the registry, which are served at the package level.
|
||||
if url.is_none() {
|
||||
let versions_response = if let Some(index) = index {
|
||||
in_memory.explicit().get(&(name.clone(), index.clone()))
|
||||
} else {
|
||||
in_memory.implicit().get(name)
|
||||
};
|
||||
// Query the implicit and explicit indexes (lazily) for the hashes.
|
||||
let implicit_response = in_memory.implicit().get(name);
|
||||
let mut explicit_response = None;
|
||||
|
||||
if let Some(versions_response) = versions_response {
|
||||
if let VersionsResponse::Found(ref version_maps) = *versions_response {
|
||||
if let Some(digests) = version_maps
|
||||
.iter()
|
||||
.find_map(|version_map| version_map.hashes(version))
|
||||
.map(|digests| {
|
||||
let mut digests = HashDigests::from(digests);
|
||||
digests.sort_unstable();
|
||||
digests
|
||||
})
|
||||
{
|
||||
if !digests.is_empty() {
|
||||
return digests;
|
||||
}
|
||||
// Search in the implicit indexes.
|
||||
let hashes = implicit_response
|
||||
.as_ref()
|
||||
.and_then(|response| {
|
||||
if let VersionsResponse::Found(version_maps) = &**response {
|
||||
Some(version_maps)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|version_map| version_map.index() == index)
|
||||
.find_map(|version_map| version_map.hashes(version))
|
||||
.or_else(|| {
|
||||
// Search in the explicit indexes.
|
||||
explicit_response = index
|
||||
.and_then(|index| in_memory.explicit().get(&(name.clone(), index.clone())));
|
||||
explicit_response
|
||||
.as_ref()
|
||||
.and_then(|response| {
|
||||
if let VersionsResponse::Found(version_maps) = &**response {
|
||||
Some(version_maps)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|version_map| version_map.index() == index)
|
||||
.find_map(|version_map| version_map.hashes(version))
|
||||
});
|
||||
|
||||
if let Some(hashes) = hashes {
|
||||
let mut digests = HashDigests::from(hashes);
|
||||
digests.sort_unstable();
|
||||
if !digests.is_empty() {
|
||||
return digests;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2819,6 +2819,27 @@ impl ForkState {
|
|||
self
|
||||
}
|
||||
|
||||
/// Returns the URL or index for a package and version.
|
||||
///
|
||||
/// In practice, exactly one of the returned values will be `Some`.
|
||||
fn source(
|
||||
&self,
|
||||
name: &PackageName,
|
||||
version: &Version,
|
||||
) -> (Option<&VerbatimParsedUrl>, Option<&IndexUrl>) {
|
||||
let url = self.fork_urls.get(name);
|
||||
let index = url
|
||||
.is_none()
|
||||
.then(|| {
|
||||
self.pins
|
||||
.get(name, version)
|
||||
.expect("Every package should be pinned")
|
||||
.index()
|
||||
})
|
||||
.flatten();
|
||||
(url, index)
|
||||
}
|
||||
|
||||
fn into_resolution(self) -> Resolution {
|
||||
let solution: FxHashMap<_, _> = self.pubgrub.partial_solution.extract_solution().collect();
|
||||
let edge_count: usize = solution
|
||||
|
@ -2865,10 +2886,10 @@ impl ForkState {
|
|||
|
||||
_ => continue,
|
||||
};
|
||||
let self_url = self_name.as_ref().and_then(|name| self.fork_urls.get(name));
|
||||
let self_index = self_name
|
||||
.as_ref()
|
||||
.and_then(|name| self.fork_indexes.get(name));
|
||||
|
||||
let (self_url, self_index) = self_name
|
||||
.map(|self_name| self.source(self_name, self_version))
|
||||
.unwrap_or((None, None));
|
||||
|
||||
match **dependency_package {
|
||||
PubGrubPackageInner::Package {
|
||||
|
@ -2894,8 +2915,8 @@ impl ForkState {
|
|||
}
|
||||
}
|
||||
|
||||
let to_url = self.fork_urls.get(dependency_name);
|
||||
let to_index = self.fork_indexes.get(dependency_name);
|
||||
let (to_url, to_index) = self.source(dependency_name, dependency_version);
|
||||
|
||||
let edge = ResolutionDependencyEdge {
|
||||
from: self_name.cloned(),
|
||||
from_version: self_version.clone(),
|
||||
|
@ -2926,8 +2947,8 @@ impl ForkState {
|
|||
}
|
||||
}
|
||||
|
||||
let to_url = self.fork_urls.get(dependency_name);
|
||||
let to_index = self.fork_indexes.get(dependency_name);
|
||||
let (to_url, to_index) = self.source(dependency_name, dependency_version);
|
||||
|
||||
let edge = ResolutionDependencyEdge {
|
||||
from: self_name.cloned(),
|
||||
from_version: self_version.clone(),
|
||||
|
@ -2957,10 +2978,9 @@ impl ForkState {
|
|||
"Extras should be flattened"
|
||||
);
|
||||
}
|
||||
let (to_url, to_index) = self.source(dependency_name, dependency_version);
|
||||
|
||||
// Insert an edge from the dependent package to the extra package.
|
||||
let to_url = self.fork_urls.get(dependency_name);
|
||||
let to_index = self.fork_indexes.get(dependency_name);
|
||||
let edge = ResolutionDependencyEdge {
|
||||
from: self_name.cloned(),
|
||||
from_version: self_version.clone(),
|
||||
|
@ -2979,8 +2999,6 @@ impl ForkState {
|
|||
edges.push(edge);
|
||||
|
||||
// Insert an edge from the dependent package to the base package.
|
||||
let to_url = self.fork_urls.get(dependency_name);
|
||||
let to_index = self.fork_indexes.get(dependency_name);
|
||||
let edge = ResolutionDependencyEdge {
|
||||
from: self_name.cloned(),
|
||||
from_version: self_version.clone(),
|
||||
|
@ -3009,10 +3027,10 @@ impl ForkState {
|
|||
"Groups should be flattened"
|
||||
);
|
||||
|
||||
let (to_url, to_index) = self.source(dependency_name, dependency_version);
|
||||
|
||||
// Add an edge from the dependent package to the dev package, but _not_ the
|
||||
// base package.
|
||||
let to_url = self.fork_urls.get(dependency_name);
|
||||
let to_index = self.fork_indexes.get(dependency_name);
|
||||
let edge = ResolutionDependencyEdge {
|
||||
from: self_name.cloned(),
|
||||
from_version: self_version.clone(),
|
||||
|
@ -3046,13 +3064,14 @@ impl ForkState {
|
|||
marker: MarkerTree::TRUE,
|
||||
} = &*self.pubgrub.package_store[package]
|
||||
{
|
||||
let (url, index) = self.source(name, &version);
|
||||
Some((
|
||||
ResolutionPackage {
|
||||
name: name.clone(),
|
||||
extra: extra.clone(),
|
||||
dev: dev.clone(),
|
||||
url: self.fork_urls.get(name).cloned(),
|
||||
index: self.fork_indexes.get(name).cloned(),
|
||||
url: url.cloned(),
|
||||
index: index.cloned(),
|
||||
},
|
||||
version,
|
||||
))
|
||||
|
@ -3091,10 +3110,9 @@ pub(crate) struct ResolutionPackage {
|
|||
pub(crate) name: PackageName,
|
||||
pub(crate) extra: Option<ExtraName>,
|
||||
pub(crate) dev: Option<GroupName>,
|
||||
/// For index packages, this is `None`.
|
||||
/// For registry packages, this is `None`; otherwise, the direct URL of the distribution.
|
||||
pub(crate) url: Option<VerbatimParsedUrl>,
|
||||
/// For URL packages, this is `None`, and is only `Some` for packages that are pinned to a
|
||||
/// specific index via `tool.uv.sources`.
|
||||
/// For URL packages, this is `None`; otherwise, the index URL of the distribution.
|
||||
pub(crate) index: Option<IndexUrl>,
|
||||
}
|
||||
|
||||
|
|
|
@ -203,13 +203,10 @@ impl VersionMap {
|
|||
/// Return the [`Hashes`] for the given version, if any.
|
||||
pub(crate) fn hashes(&self, version: &Version) -> Option<&[HashDigest]> {
|
||||
match self.inner {
|
||||
VersionMapInner::Eager(ref eager) => eager
|
||||
.map
|
||||
.get(version)
|
||||
.map(uv_distribution_types::PrioritizedDist::hashes),
|
||||
VersionMapInner::Lazy(ref lazy) => lazy
|
||||
.get(version)
|
||||
.map(uv_distribution_types::PrioritizedDist::hashes),
|
||||
VersionMapInner::Eager(ref eager) => {
|
||||
eager.map.get(version).map(PrioritizedDist::hashes)
|
||||
}
|
||||
VersionMapInner::Lazy(ref lazy) => lazy.get(version).map(PrioritizedDist::hashes),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue