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
+
1
12
use std:: collections:: { HashMap , HashSet } ;
2
13
use std:: task:: { ready, Poll } ;
3
14
@@ -15,9 +26,15 @@ use anyhow::{bail, Context as _};
15
26
use tracing:: { debug, trace} ;
16
27
use url:: Url ;
17
28
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.
19
35
///
20
- /// See also `core::Source`.
36
+ /// See also the [`Source`] trait, as many of the methods here mirror and
37
+ /// abstract over its functionalities.
21
38
pub trait Registry {
22
39
/// Attempt to find the packages that match a dependency request.
23
40
fn query (
@@ -27,6 +44,8 @@ pub trait Registry {
27
44
f : & mut dyn FnMut ( IndexSummary ) ,
28
45
) -> Poll < CargoResult < ( ) > > ;
29
46
47
+ /// Gathers the result from [`Registry::query`] as a list of [`IndexSummary`] items
48
+ /// when they become available.
30
49
fn query_vec (
31
50
& mut self ,
32
51
dep : & Dependency ,
@@ -36,34 +55,40 @@ pub trait Registry {
36
55
self . query ( dep, kind, & mut |s| ret. push ( s) ) . map_ok ( |( ) | ret)
37
56
}
38
57
58
+ /// Gets the description of a source, to provide useful messages.
39
59
fn describe_source ( & self , source : SourceId ) -> String ;
60
+
61
+ /// Checks if a source is replaced with some other source.
40
62
fn is_replaced ( & self , source : SourceId ) -> bool ;
41
63
42
- /// Block until all outstanding Poll::Pending requests are Poll::Ready.
64
+ /// Block until all outstanding [` Poll::Pending`] requests are [` Poll::Ready`] .
43
65
fn block_until_ready ( & mut self ) -> CargoResult < ( ) > ;
44
66
}
45
67
46
68
/// 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.
49
71
///
50
72
/// 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.
54
76
///
55
77
/// 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
58
80
/// operations if necessary) and is ready to be queried for packages.
81
+ ///
82
+ /// [`Package`]: crate::core::Package
59
83
pub struct PackageRegistry < ' gctx > {
60
84
gctx : & ' gctx GlobalContext ,
61
85
sources : SourceMap < ' gctx > ,
62
86
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.
65
89
overrides : Vec < SourceId > ,
66
90
91
+ /// Use for tracking sources that are already loaded into the registry.
67
92
// Note that each SourceId does not take into account its `precise` field
68
93
// when hashing or testing for equality. When adding a new `SourceId`, we
69
94
// want to avoid duplicates in the `SourceMap` (to prevent re-updating the
@@ -81,11 +106,17 @@ pub struct PackageRegistry<'gctx> {
81
106
// what exactly the key is.
82
107
source_ids : HashMap < SourceId , ( SourceId , Kind ) > ,
83
108
109
+ /// This is constructed via [`PackageRegistry::register_lock`].
110
+ /// See also [`LockedMap`].
84
111
locked : LockedMap ,
112
+ /// A group of packages tha allows to use even when yanked.
85
113
yanked_whitelist : HashSet < PackageId > ,
86
114
source_config : SourceConfigMap < ' gctx > ,
87
115
88
116
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.
89
120
patches_locked : bool ,
90
121
patches_available : HashMap < CanonicalUrl , Vec < PackageId > > ,
91
122
}
@@ -110,14 +141,23 @@ type LockedMap = HashMap<
110
141
Vec < ( PackageId , Vec < PackageId > ) > ,
111
142
> ;
112
143
144
+ /// Kinds of sources a [`PackageRegistry`] has loaded.
113
145
#[ derive( PartialEq , Eq , Clone , Copy ) ]
114
146
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
115
150
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.
116
155
Locked ,
156
+ /// A source that is not locked nor a path-override.
117
157
Normal ,
118
158
}
119
159
120
- /// Argument to `PackageRegistry::patch` which is information about a `[patch]`
160
+ /// Argument to [ `PackageRegistry::patch`] which is information about a `[patch]`
121
161
/// directive that we found in a lockfile, if present.
122
162
pub struct LockedPatchDependency {
123
163
/// The original `Dependency` directive, except "locked" so it's version
@@ -154,6 +194,8 @@ impl<'gctx> PackageRegistry<'gctx> {
154
194
PackageSet :: new ( package_ids, self . sources , self . gctx )
155
195
}
156
196
197
+ /// Ensures the [`Source`] of the given [`SourceId`] is loaded.
198
+ /// If not, this will block until the source is ready.
157
199
fn ensure_loaded ( & mut self , namespace : SourceId , kind : Kind ) -> CargoResult < ( ) > {
158
200
match self . source_ids . get ( & namespace) {
159
201
// We've previously loaded this source, and we've already locked it,
@@ -203,21 +245,28 @@ impl<'gctx> PackageRegistry<'gctx> {
203
245
Ok ( ( ) )
204
246
}
205
247
248
+ /// Adds a source which will be locked.
249
+ /// Useful for path sources such as the source of a workspace member.
206
250
pub fn add_preloaded ( & mut self , source : Box < dyn Source + ' gctx > ) {
207
251
self . add_source ( source, Kind :: Locked ) ;
208
252
}
209
253
254
+ /// Adds a source to the registry.
210
255
fn add_source ( & mut self , source : Box < dyn Source + ' gctx > , kind : Kind ) {
211
256
let id = source. source_id ( ) ;
212
257
self . sources . insert ( source) ;
213
258
self . source_ids . insert ( id, ( id, kind) ) ;
214
259
}
215
260
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
216
264
pub fn add_override ( & mut self , source : Box < dyn Source + ' gctx > ) {
217
265
self . overrides . push ( source. source_id ( ) ) ;
218
266
self . add_source ( source, Kind :: Override ) ;
219
267
}
220
268
269
+ /// Allows a group of package to be available to query even if they are yanked.
221
270
pub fn add_to_yanked_whitelist ( & mut self , iter : impl Iterator < Item = PackageId > ) {
222
271
let pkgs = iter. collect :: < Vec < _ > > ( ) ;
223
272
for ( _, source) in self . sources . sources_mut ( ) {
@@ -232,6 +281,8 @@ impl<'gctx> PackageRegistry<'gctx> {
232
281
self . locked = HashMap :: new ( ) ;
233
282
}
234
283
284
+ /// Registers one "locked package" to the registry, for guiding the
285
+ /// dependency resolution. See [`LockedMap`] for more.
235
286
pub fn register_lock ( & mut self , id : PackageId , deps : Vec < PackageId > ) {
236
287
trace ! ( "register_lock: {}" , id) ;
237
288
for dep in deps. iter ( ) {
@@ -262,8 +313,8 @@ impl<'gctx> PackageRegistry<'gctx> {
262
313
/// entries in `Cargo.lock`.
263
314
///
264
315
/// 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.
267
318
///
268
319
/// The return value is a `Vec` of patches that should *not* be locked.
269
320
/// This happens when the patch is locked, but the patch has been updated
@@ -434,13 +485,8 @@ impl<'gctx> PackageRegistry<'gctx> {
434
485
Ok ( unlock_patches)
435
486
}
436
487
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`].
444
490
pub fn lock_patches ( & mut self ) {
445
491
assert ! ( !self . patches_locked) ;
446
492
for summaries in self . patches . values_mut ( ) {
@@ -452,14 +498,16 @@ impl<'gctx> PackageRegistry<'gctx> {
452
498
self . patches_locked = true ;
453
499
}
454
500
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.
456
502
///
457
503
/// These patches are mainly collected from [`patch`](Self::patch).
458
504
/// They might not be the same as patches actually used during dependency resolving.
459
505
pub fn patches ( & self ) -> & HashMap < CanonicalUrl , Vec < Summary > > {
460
506
& self . patches
461
507
}
462
508
509
+ /// Loads the [`Source`] for a given [`SourceId`] to this registry, making
510
+ /// them available to resolution.
463
511
fn load ( & mut self , source_id : SourceId , kind : Kind ) -> CargoResult < ( ) > {
464
512
debug ! ( "loading source {}" , source_id) ;
465
513
let source = self
@@ -488,6 +536,7 @@ impl<'gctx> PackageRegistry<'gctx> {
488
536
Ok ( ( ) )
489
537
}
490
538
539
+ /// Queries path overrides from this registry.
491
540
fn query_overrides ( & mut self , dep : & Dependency ) -> Poll < CargoResult < Option < IndexSummary > > > {
492
541
for & s in self . overrides . iter ( ) {
493
542
let src = self . sources . get_mut ( s) . unwrap ( ) ;
@@ -753,6 +802,7 @@ impl<'gctx> Registry for PackageRegistry<'gctx> {
753
802
}
754
803
}
755
804
805
+ /// See [`PackageRegistry::lock`].
756
806
fn lock (
757
807
locked : & LockedMap ,
758
808
patches : & HashMap < CanonicalUrl , Vec < PackageId > > ,
0 commit comments