Skip to content

Commit 4113935

Browse files
committed
Auto merge of #13698 - weihanglo:registry-doc, r=ehuss
doc: comments on `PackageRegistry`
2 parents 81ca704 + bbb7520 commit 4113935

File tree

1 file changed

+73
-23
lines changed

1 file changed

+73
-23
lines changed

src/cargo/core/registry.rs

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
//! Types that hold source information for a group of packages.
2+
//!
3+
//! The primary type you're looking for is [`PackageRegistry`]. It is an
4+
//! abstraction over multiple [`Source`]s. [`PackageRegistry`] also implements
5+
//! the [`Registry`] trait, allowing a dependency resolver to query necessary
6+
//! package metadata (i.e., [Summary]) from it.
7+
//!
8+
//! Not to be confused with [`crate::sources::registry`] and [`crate::ops::registry`].
9+
//! The former is just one kind of source,
10+
//! while the latter involves operations on the registry Web API.
11+
112
use std::collections::{HashMap, HashSet};
213
use std::task::{ready, Poll};
314

@@ -15,9 +26,15 @@ use anyhow::{bail, Context as _};
1526
use tracing::{debug, trace};
1627
use url::Url;
1728

18-
/// Source of information about a group of packages.
29+
/// An abstraction provides a set of methods for querying source information
30+
/// about a group of packages, without leaking too much implementation details
31+
/// of the actual registry.
32+
///
33+
/// As of 2024-04, only [`PackageRegistry`] and `MyRegistry` in resolver-tests
34+
/// are found implementing this.
1935
///
20-
/// See also `core::Source`.
36+
/// See also the [`Source`] trait, as many of the methods here mirror and
37+
/// abstract over its functionalities.
2138
pub trait Registry {
2239
/// Attempt to find the packages that match a dependency request.
2340
fn query(
@@ -27,6 +44,8 @@ pub trait Registry {
2744
f: &mut dyn FnMut(IndexSummary),
2845
) -> Poll<CargoResult<()>>;
2946

47+
/// Gathers the result from [`Registry::query`] as a list of [`IndexSummary`] items
48+
/// when they become available.
3049
fn query_vec(
3150
&mut self,
3251
dep: &Dependency,
@@ -36,34 +55,40 @@ pub trait Registry {
3655
self.query(dep, kind, &mut |s| ret.push(s)).map_ok(|()| ret)
3756
}
3857

58+
/// Gets the description of a source, to provide useful messages.
3959
fn describe_source(&self, source: SourceId) -> String;
60+
61+
/// Checks if a source is replaced with some other source.
4062
fn is_replaced(&self, source: SourceId) -> bool;
4163

42-
/// Block until all outstanding Poll::Pending requests are Poll::Ready.
64+
/// Block until all outstanding [`Poll::Pending`] requests are [`Poll::Ready`].
4365
fn block_until_ready(&mut self) -> CargoResult<()>;
4466
}
4567

4668
/// This structure represents a registry of known packages. It internally
47-
/// contains a number of `Box<Source>` instances which are used to load a
48-
/// `Package` from.
69+
/// contains a number of [`Source`] instances which are used to load a
70+
/// [`Package`] from.
4971
///
5072
/// The resolution phase of Cargo uses this to drive knowledge about new
51-
/// packages as well as querying for lists of new packages. It is here that
52-
/// sources are updated (e.g., network operations) and overrides are
53-
/// handled.
73+
/// packages as well as querying for lists of new packages.
74+
/// It is here that sources are updated (e.g., network operations) and
75+
/// overrides/patches are handled.
5476
///
5577
/// The general idea behind this registry is that it is centered around the
56-
/// `SourceMap` structure, contained within which is a mapping of a `SourceId` to
57-
/// a `Source`. Each `Source` in the map has been updated (using network
78+
/// [`SourceMap`] structure, contained within which is a mapping of a [`SourceId`]
79+
/// to a [`Source`]. Each [`Source`] in the map has been updated (using network
5880
/// operations if necessary) and is ready to be queried for packages.
81+
///
82+
/// [`Package`]: crate::core::Package
5983
pub struct PackageRegistry<'gctx> {
6084
gctx: &'gctx GlobalContext,
6185
sources: SourceMap<'gctx>,
6286

63-
// A list of sources which are considered "overrides" which take precedent
64-
// when querying for packages.
87+
/// A list of sources which are considered "path-overrides" which take
88+
/// precedent when querying for packages.
6589
overrides: Vec<SourceId>,
6690

91+
/// Use for tracking sources that are already loaded into the registry.
6792
// Note that each SourceId does not take into account its `precise` field
6893
// when hashing or testing for equality. When adding a new `SourceId`, we
6994
// want to avoid duplicates in the `SourceMap` (to prevent re-updating the
@@ -81,11 +106,17 @@ pub struct PackageRegistry<'gctx> {
81106
// what exactly the key is.
82107
source_ids: HashMap<SourceId, (SourceId, Kind)>,
83108

109+
/// This is constructed via [`PackageRegistry::register_lock`].
110+
/// See also [`LockedMap`].
84111
locked: LockedMap,
112+
/// A group of packages tha allows to use even when yanked.
85113
yanked_whitelist: HashSet<PackageId>,
86114
source_config: SourceConfigMap<'gctx>,
87115

88116
patches: HashMap<CanonicalUrl, Vec<Summary>>,
117+
/// Whether patches are locked. That is, they are available to resolution.
118+
///
119+
/// See [`PackageRegistry::lock_patches`] and [`PackageRegistry::patch`] for more.
89120
patches_locked: bool,
90121
patches_available: HashMap<CanonicalUrl, Vec<PackageId>>,
91122
}
@@ -110,14 +141,23 @@ type LockedMap = HashMap<
110141
Vec<(PackageId, Vec<PackageId>)>,
111142
>;
112143

144+
/// Kinds of sources a [`PackageRegistry`] has loaded.
113145
#[derive(PartialEq, Eq, Clone, Copy)]
114146
enum Kind {
147+
/// A source from a [path override].
148+
///
149+
/// [path overrides]: https://doc.rust-lang.org/nightly/cargo/reference/overriding-dependencies.html#paths-overrides
115150
Override,
151+
/// A source that is locked and not going to change.
152+
///
153+
/// For example, sources of workspace members are loaded during the
154+
/// workspace initialization, so not allowed to change.
116155
Locked,
156+
/// A source that is not locked nor a path-override.
117157
Normal,
118158
}
119159

120-
/// Argument to `PackageRegistry::patch` which is information about a `[patch]`
160+
/// Argument to [`PackageRegistry::patch`] which is information about a `[patch]`
121161
/// directive that we found in a lockfile, if present.
122162
pub struct LockedPatchDependency {
123163
/// The original `Dependency` directive, except "locked" so it's version
@@ -154,6 +194,8 @@ impl<'gctx> PackageRegistry<'gctx> {
154194
PackageSet::new(package_ids, self.sources, self.gctx)
155195
}
156196

197+
/// Ensures the [`Source`] of the given [`SourceId`] is loaded.
198+
/// If not, this will block until the source is ready.
157199
fn ensure_loaded(&mut self, namespace: SourceId, kind: Kind) -> CargoResult<()> {
158200
match self.source_ids.get(&namespace) {
159201
// We've previously loaded this source, and we've already locked it,
@@ -203,21 +245,28 @@ impl<'gctx> PackageRegistry<'gctx> {
203245
Ok(())
204246
}
205247

248+
/// Adds a source which will be locked.
249+
/// Useful for path sources such as the source of a workspace member.
206250
pub fn add_preloaded(&mut self, source: Box<dyn Source + 'gctx>) {
207251
self.add_source(source, Kind::Locked);
208252
}
209253

254+
/// Adds a source to the registry.
210255
fn add_source(&mut self, source: Box<dyn Source + 'gctx>, kind: Kind) {
211256
let id = source.source_id();
212257
self.sources.insert(source);
213258
self.source_ids.insert(id, (id, kind));
214259
}
215260

261+
/// Adds a source from a [path override].
262+
///
263+
/// [path override]: https://doc.rust-lang.org/nightly/cargo/reference/overriding-dependencies.html#paths-overrides
216264
pub fn add_override(&mut self, source: Box<dyn Source + 'gctx>) {
217265
self.overrides.push(source.source_id());
218266
self.add_source(source, Kind::Override);
219267
}
220268

269+
/// Allows a group of package to be available to query even if they are yanked.
221270
pub fn add_to_yanked_whitelist(&mut self, iter: impl Iterator<Item = PackageId>) {
222271
let pkgs = iter.collect::<Vec<_>>();
223272
for (_, source) in self.sources.sources_mut() {
@@ -232,6 +281,8 @@ impl<'gctx> PackageRegistry<'gctx> {
232281
self.locked = HashMap::new();
233282
}
234283

284+
/// Registers one "locked package" to the registry, for guiding the
285+
/// dependency resolution. See [`LockedMap`] for more.
235286
pub fn register_lock(&mut self, id: PackageId, deps: Vec<PackageId>) {
236287
trace!("register_lock: {}", id);
237288
for dep in deps.iter() {
@@ -262,8 +313,8 @@ impl<'gctx> PackageRegistry<'gctx> {
262313
/// entries in `Cargo.lock`.
263314
///
264315
/// Note that the patch list specified here *will not* be available to
265-
/// `query` until `lock_patches` is called below, which should be called
266-
/// once all patches have been added.
316+
/// [`Registry::query`] until [`PackageRegistry::lock_patches`] is called
317+
/// below, which should be called once all patches have been added.
267318
///
268319
/// The return value is a `Vec` of patches that should *not* be locked.
269320
/// This happens when the patch is locked, but the patch has been updated
@@ -434,13 +485,8 @@ impl<'gctx> PackageRegistry<'gctx> {
434485
Ok(unlock_patches)
435486
}
436487

437-
/// Lock all patch summaries added via `patch`, making them available to
438-
/// resolution via `query`.
439-
///
440-
/// This function will internally `lock` each summary added via `patch`
441-
/// above now that the full set of `patch` packages are known. This'll allow
442-
/// us to correctly resolve overridden dependencies between patches
443-
/// hopefully!
488+
/// Lock all patch summaries added via [`patch`](Self::patch),
489+
/// making them available to resolution via [`Registry::query`].
444490
pub fn lock_patches(&mut self) {
445491
assert!(!self.patches_locked);
446492
for summaries in self.patches.values_mut() {
@@ -452,14 +498,16 @@ impl<'gctx> PackageRegistry<'gctx> {
452498
self.patches_locked = true;
453499
}
454500

455-
/// Gets all patches grouped by the source URLS they are going to patch.
501+
/// Gets all patches grouped by the source URLs they are going to patch.
456502
///
457503
/// These patches are mainly collected from [`patch`](Self::patch).
458504
/// They might not be the same as patches actually used during dependency resolving.
459505
pub fn patches(&self) -> &HashMap<CanonicalUrl, Vec<Summary>> {
460506
&self.patches
461507
}
462508

509+
/// Loads the [`Source`] for a given [`SourceId`] to this registry, making
510+
/// them available to resolution.
463511
fn load(&mut self, source_id: SourceId, kind: Kind) -> CargoResult<()> {
464512
debug!("loading source {}", source_id);
465513
let source = self
@@ -488,6 +536,7 @@ impl<'gctx> PackageRegistry<'gctx> {
488536
Ok(())
489537
}
490538

539+
/// Queries path overrides from this registry.
491540
fn query_overrides(&mut self, dep: &Dependency) -> Poll<CargoResult<Option<IndexSummary>>> {
492541
for &s in self.overrides.iter() {
493542
let src = self.sources.get_mut(s).unwrap();
@@ -753,6 +802,7 @@ impl<'gctx> Registry for PackageRegistry<'gctx> {
753802
}
754803
}
755804

805+
/// See [`PackageRegistry::lock`].
756806
fn lock(
757807
locked: &LockedMap,
758808
patches: &HashMap<CanonicalUrl, Vec<PackageId>>,

0 commit comments

Comments
 (0)