From c5da8a4b7ac691bf0ade1cd8aefdfe1ac67921e5 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 00:07:04 +0100 Subject: [PATCH 1/7] docs: docs for arguments of `RegistrySource::new` --- src/cargo/sources/registry/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index bedc1afc528..05218ac8bf2 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -485,8 +485,10 @@ impl<'cfg> RegistrySource<'cfg> { /// Creates a source of a registry. This is a inner helper function. /// - /// * `name` --- Unique name for this source to store source files (`.crate` tarballs) are stored. + /// * `name` --- Name of a path segment which may affect where `.crate` + /// tarballs, the registry index and cache are stored. Expect to be unique. /// * `ops` --- The underlying [`RegistryData`] type. + /// * `yanked_whitelist` --- Packages allowed to be used, even if they are yanked. fn new( source_id: SourceId, config: &'cfg Config, From c33f703a027f49df873360882bc81e556fa40da7 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 14:35:50 +0100 Subject: [PATCH 2/7] docs: fix the wrong cache directory path --- src/cargo/util/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/util/config/mod.rs b/src/cargo/util/config/mod.rs index a9d5f5c8d53..dfd0bb19879 100644 --- a/src/cargo/util/config/mod.rs +++ b/src/cargo/util/config/mod.rs @@ -363,7 +363,7 @@ impl Config { self.registry_base_path().join("index") } - /// Gets the Cargo registry cache directory (`/registry/path`). + /// Gets the Cargo registry cache directory (`/registry/cache`). pub fn registry_cache_path(&self) -> Filesystem { self.registry_base_path().join("cache") } From 2da95e2c7b2a96c7490df32902c962d64612051b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 13:35:40 +0100 Subject: [PATCH 3/7] docs: add a link to Cargo book for download URL template --- src/cargo/sources/registry/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cargo/sources/registry/mod.rs b/src/cargo/sources/registry/mod.rs index 05218ac8bf2..4fd93b3d2a1 100644 --- a/src/cargo/sources/registry/mod.rs +++ b/src/cargo/sources/registry/mod.rs @@ -277,6 +277,9 @@ pub struct RegistryConfig { /// will be extended with `/{crate}/{version}/download` to /// support registries like crates.io which were created before the /// templating setup was created. + /// + /// For more on the template of the download URL, see [Index Configuration]( + /// https://doc.rust-lang.org/nightly/cargo/reference/registry-index.html#index-configuration). pub dl: String, /// API endpoint for the registry. This is what's actually hit to perform From 03bae5c7145c626ba116b83656df9cd20ba38ab5 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 13:31:18 +0100 Subject: [PATCH 4/7] docs: doc comments for registry downloads --- src/cargo/sources/registry/download.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/cargo/sources/registry/download.rs b/src/cargo/sources/registry/download.rs index ac3bca024c8..8450e56ee9a 100644 --- a/src/cargo/sources/registry/download.rs +++ b/src/cargo/sources/registry/download.rs @@ -1,3 +1,8 @@ +//! Shared download logic between [`HttpRegistry`] and [`RemoteRegistry`]. +//! +//! [`HttpRegistry`]: super::http_remote::HttpRegistry +//! [`RemoteRegistry`]: super::remote::RemoteRegistry + use anyhow::Context; use cargo_util::Sha256; @@ -20,10 +25,15 @@ const PREFIX_TEMPLATE: &str = "{prefix}"; const LOWER_PREFIX_TEMPLATE: &str = "{lowerprefix}"; const CHECKSUM_TEMPLATE: &str = "{sha256-checksum}"; +/// Filename of the `.crate` tarball, e.g., `once_cell-1.18.0.crate`. pub(super) fn filename(pkg: PackageId) -> String { format!("{}-{}.crate", pkg.name(), pkg.version()) } +/// Checks if `pkg` is downloaded and ready under the directory at `cache_path`. +/// If not, returns a URL to download it from. +/// +/// This is primarily called by [`RegistryData::download`](super::RegistryData::download). pub(super) fn download( cache_path: &Filesystem, config: &Config, @@ -86,6 +96,10 @@ pub(super) fn download( }) } +/// Verifies the integrity of `data` with `checksum` and persists it under the +/// directory at `cache_path`. +/// +/// This is primarily called by [`RegistryData::finish_download`](super::RegistryData::finish_download). pub(super) fn finish_download( cache_path: &Filesystem, config: &Config, @@ -119,6 +133,10 @@ pub(super) fn finish_download( Ok(dst) } +/// Checks if a tarball of `pkg` has been already downloaded under the +/// directory at `cache_path`. +/// +/// This is primarily called by [`RegistryData::is_crate_downloaded`](super::RegistryData::is_crate_downloaded). pub(super) fn is_crate_downloaded( cache_path: &Filesystem, config: &Config, From 1bc13e964353d12518ca2a7a084b6e958186d4f3 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 00:05:59 +0100 Subject: [PATCH 5/7] docs: doc comments for local registry --- src/cargo/sources/registry/local.rs | 54 ++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/cargo/sources/registry/local.rs b/src/cargo/sources/registry/local.rs index 89419191f97..fdcdc753ca5 100644 --- a/src/cargo/sources/registry/local.rs +++ b/src/cargo/sources/registry/local.rs @@ -1,3 +1,5 @@ +//! Access to a regstiry on the local filesystem. See [`LocalRegistry`] for more. + use crate::core::PackageId; use crate::sources::registry::{LoadResponse, MaybeLock, RegistryConfig, RegistryData}; use crate::util::errors::CargoResult; @@ -10,18 +12,68 @@ use std::path::Path; use std::task::Poll; /// A local registry is a registry that lives on the filesystem as a set of -/// `.crate` files with an `index` directory in the same format as a remote +/// `.crate` files with an `index` directory in the [same format] as a remote /// registry. +/// +/// This type is primarily accessed through the [`RegistryData`] trait. +/// +/// When a local registry is requested for a package, it simply looks into what +/// its index has under the `index` directory. When [`LocalRegistry::download`] +/// is called, a local registry verifies the checksum of the requested `.crate` +/// tarball and then unpacks it to `$CARGO_HOME/.registry/src`. +/// +/// > Note that there is a third-party subcommand [`cargo-local-registry`], +/// > which happened to be developed by a former Cargo team member when local +/// > registry was introduced. The tool is to ease the burden of maintaining +/// > local registries. However, in general the Cargo team avoids recommending +/// > any specific third-party crate. Just FYI. +/// +/// [same format]: super#the-format-of-the-index +/// [`cargo-local-registry`]: https://crates.io/crates/cargo-local-registry +/// +/// # Filesystem hierarchy +/// +/// Here is an example layout of a local registry on a local filesystem: +/// +/// ```text +/// [registry root]/ +/// ├── index/ # registry index +/// │ ├── an/ +/// │ │ └── yh/ +/// │ │ └── anyhow +/// │ ├── ru/ +/// │ │ └── st/ +/// │ │ ├── rustls +/// │ │ └── rustls-ffi +/// │ └── se/ +/// │ └── mv/ +/// │ └── semver +/// ├── anyhow-1.0.71.crate # pre-downloaded crate tarballs +/// ├── rustls-0.20.8.crate +/// ├── rustls-ffi-0.8.2.crate +/// └── semver-1.0.17.crate +/// ``` +/// +/// For general concepts of registries, see the [module-level documentation](crate::sources::registry). pub struct LocalRegistry<'cfg> { + /// Path to the registry index. index_path: Filesystem, + /// Root path of this local registry. root: Filesystem, + /// Path where this local registry extract `.crate` tarballs to. src_path: Filesystem, config: &'cfg Config, + /// Whether this source has updated all package informations it may contain. updated: bool, + /// Disables status messages. quiet: bool, } impl<'cfg> LocalRegistry<'cfg> { + /// Creates a local registry at `root`. + /// + /// * `name` --- Name of a path segment where `.crate` tarballs are stored. + /// Expect to be unique. pub fn new(root: &Path, config: &'cfg Config, name: &str) -> LocalRegistry<'cfg> { LocalRegistry { src_path: config.registry_source_path().join(name), From eb6c745fb1ecb75f775132f3093efc7aa86b7a3b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 00:41:50 +0100 Subject: [PATCH 6/7] docs: doc comments for remote registry --- src/cargo/sources/registry/remote.rs | 109 +++++++++++++++++++++------ 1 file changed, 88 insertions(+), 21 deletions(-) diff --git a/src/cargo/sources/registry/remote.rs b/src/cargo/sources/registry/remote.rs index f4df4e86b11..f1c9be4f887 100644 --- a/src/cargo/sources/registry/remote.rs +++ b/src/cargo/sources/registry/remote.rs @@ -1,3 +1,5 @@ +//! Access to a Git index based registry. See [`RemoteRegistry`] for details. + use crate::core::{GitReference, PackageId, SourceId}; use crate::sources::git; use crate::sources::git::fetch::RemoteKind; @@ -21,29 +23,73 @@ use std::task::{ready, Poll}; /// A remote registry is a registry that lives at a remote URL (such as /// crates.io). The git index is cloned locally, and `.crate` files are /// downloaded as needed and cached locally. +/// +/// This type is primarily accessed through the [`RegistryData`] trait. +/// +/// See the [module-level documentation](super) for the index format and layout. +/// +/// ## History of Git-based index registry +/// +/// Using Git to host this index used to be quite efficient. The full index can +/// be stored efficiently locally on disk, and once it is downloaded, all +/// queries of a registry can happen locally and needn't touch the network. +/// Git-based index was a reasonable design choice at the time when HTTP/2 +/// was just introduced. +/// +/// However, the full index keeps growing as crates.io grows. It becomes +/// relatively big and slows down the first use of Cargo. Git (specifically +/// libgit2) is not efficient at handling huge amounts of small files either. +/// On the other hand, newer protocols like HTTP/2 are prevalent and capable to +/// serve a bunch of tiny files. Today, it is encouraged to use [`HttpRegistry`], +/// which is the default from 1.70.0. That being said, Cargo will continue +/// supporting Git-based index for a pretty long while. +/// +/// [`HttpRegistry`]: super::http_remote::HttpRegistry pub struct RemoteRegistry<'cfg> { + /// Path to the registry index (`$CARGO_HOME/registry/index/$REG-HASH`). index_path: Filesystem, - /// Path to the cache of `.crate` files (`$CARGO_HOME/registry/path/$REG-HASH`). + /// Path to the cache of `.crate` files (`$CARGO_HOME/registry/cache/$REG-HASH`). cache_path: Filesystem, + /// The unique identifier of this registry source. source_id: SourceId, + /// This reference is stored so that when a registry needs update, it knows + /// where to fetch from. index_git_ref: GitReference, config: &'cfg Config, + /// A Git [tree object] to help this registry find crate metadata from the + /// underlying Git repository. + /// + /// This is stored here to prevent Git from repeatly creating a tree object + /// during each call into `load()`. + /// + /// [tree object]: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_tree_objects tree: RefCell>>, + /// A Git repository that contains the actual index we want. repo: LazyCell, + /// The current HEAD commit of the underlying Git repository. head: Cell>, + /// This stores sha value of the current HEAD commit for convenience. current_sha: Cell>, - needs_update: bool, // Does this registry need to be updated? + /// Whether this registry needs to update package informations. + /// + /// See [`RemoteRegistry::mark_updated`] on how to make sure a registry + /// index is updated only once per session. + needs_update: bool, + /// Disables status messages. quiet: bool, } impl<'cfg> RemoteRegistry<'cfg> { + /// Creates a Git-rebased remote registry for `source_id`. + /// + /// * `name` --- Name of a path segment where `.crate` tarballs and the + /// registry index are stored. Expect to be unique. pub fn new(source_id: SourceId, config: &'cfg Config, name: &str) -> RemoteRegistry<'cfg> { RemoteRegistry { index_path: config.registry_index_path().join(name), cache_path: config.registry_cache_path().join(name), source_id, config, - // TODO: we should probably make this configurable index_git_ref: GitReference::DefaultBranch, tree: RefCell::new(None), repo: LazyCell::new(), @@ -54,17 +100,16 @@ impl<'cfg> RemoteRegistry<'cfg> { } } + /// Creates intermediate dirs and initialize the repository. fn repo(&self) -> CargoResult<&git2::Repository> { self.repo.try_borrow_with(|| { let path = self.config.assert_package_cache_locked(&self.index_path); - // Fast path without a lock if let Ok(repo) = git2::Repository::open(&path) { trace!("opened a repo without a lock"); return Ok(repo); } - // Ok, now we need to lock and try the whole thing over again. trace!("acquiring registry index lock"); match git2::Repository::open(&path) { Ok(repo) => Ok(repo), @@ -97,6 +142,7 @@ impl<'cfg> RemoteRegistry<'cfg> { }) } + /// Get the object ID of the HEAD commit from the underlying Git repository. fn head(&self) -> CargoResult { if self.head.get().is_none() { let repo = self.repo()?; @@ -106,6 +152,8 @@ impl<'cfg> RemoteRegistry<'cfg> { Ok(self.head.get().unwrap()) } + /// Returns a [`git2::Tree`] object of the current HEAD commit of the + /// underlying Git repository. fn tree(&self) -> CargoResult>> { { let tree = self.tree.borrow(); @@ -117,6 +165,7 @@ impl<'cfg> RemoteRegistry<'cfg> { let commit = repo.find_commit(self.head()?)?; let tree = commit.tree()?; + // SAFETY: // Unfortunately in libgit2 the tree objects look like they've got a // reference to the repository object which means that a tree cannot // outlive the repository that it came from. Here we want to cache this @@ -134,6 +183,9 @@ impl<'cfg> RemoteRegistry<'cfg> { Ok(Ref::map(self.tree.borrow(), |s| s.as_ref().unwrap())) } + /// Gets the current version of the registry index. + /// + /// It is usually sha of the HEAD commit from the underlying Git repository. fn current_version(&self) -> Option { if let Some(sha) = self.current_sha.get() { return Some(sha); @@ -143,10 +195,16 @@ impl<'cfg> RemoteRegistry<'cfg> { Some(sha) } + /// Whether the registry is up-to-date. See [`Self::mark_updated`] for more. fn is_updated(&self) -> bool { self.config.updated_sources().contains(&self.source_id) } + /// Marks this registry as up-to-date. + /// + /// This makes sure the index is only updated once per session since it is + /// an expensive operation. This generally only happens when the resolver + /// is run multiple times, such as during `cargo publish`. fn mark_updated(&self) { self.config.updated_sources().insert(self.source_id); } @@ -156,7 +214,7 @@ const LAST_UPDATED_FILE: &str = ".last-updated"; impl<'cfg> RegistryData for RemoteRegistry<'cfg> { fn prepare(&self) -> CargoResult<()> { - self.repo()?; // create intermediate dirs and initialize the repo + self.repo()?; Ok(()) } @@ -168,13 +226,20 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { self.config.assert_package_cache_locked(path) } - // `index_version` Is a string representing the version of the file used to construct the cached copy. - // Older versions of Cargo used the single value of the hash of the HEAD commit as a `index_version`. - // This is technically correct but a little too conservative. If a new commit is fetched all cached - // files need to be regenerated even if a particular file was not changed. - // However if an old cargo has written such a file we still know how to read it, as long as we check for that hash value. - // - // Cargo now uses a hash of the file's contents as provided by git. + /// Read the general concept for `load()` on [`RegistryData::load`]. + /// + /// `index_version` is a string representing the version of the file used + /// to construct the cached copy. + /// + /// Older versions of Cargo used the single value of the hash of the HEAD + /// commit as a `index_version`. This is technically correct but a little + /// too conservative. If a new commit is fetched all cached files need to + /// be regenerated even if a particular file was not changed. + /// + /// However if an old cargo has written such a file we still know how to + /// read it, as long as we check for that hash value. + /// + /// Cargo now uses a hash of the file's contents as provided by git. fn load( &mut self, _root: &Path, @@ -187,7 +252,8 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { // Check if the cache is valid. let git_commit_hash = self.current_version(); if index_version.is_some() && index_version == git_commit_hash.as_deref() { - // This file was written by an old version of cargo, but it is still up-to-date. + // This file was written by an old version of cargo, but it is + // still up-to-date. return Poll::Ready(Ok(LoadResponse::CacheValid)); } // Note that the index calls this method and the filesystem is locked @@ -224,8 +290,8 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { match load_helper(&self, path, index_version) { Ok(result) => Poll::Ready(Ok(result)), Err(_) if !self.is_updated() => { - // If git returns an error and we haven't updated the repo, return - // pending to allow an update to try again. + // If git returns an error and we haven't updated the repo, + // return pending to allow an update to try again. self.needs_update = true; Poll::Pending } @@ -265,9 +331,6 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { self.needs_update = false; - // Make sure the index is only updated once per session since it is an - // expensive operation. This generally only happens when the resolver - // is run multiple times, such as during `cargo publish`. if self.is_updated() { return Ok(()); } @@ -321,8 +384,11 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { Ok(()) } + /// Read the general concept for `invalidate_cache()` on + /// [`RegistryData::invalidate_cache`]. + /// + /// To fully invalidate, undo [`RemoteRegistry::mark_updated`]'s work. fn invalidate_cache(&mut self) { - // To fully invalidate, undo `mark_updated`s work self.needs_update = true; } @@ -365,9 +431,10 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> { } } +/// Implemented to just be sure to drop `tree` field before our other fields. +/// See SAFETY inside [`RemoteRegistry::tree()`] for more. impl<'cfg> Drop for RemoteRegistry<'cfg> { fn drop(&mut self) { - // Just be sure to drop this before our other fields self.tree.borrow_mut().take(); } } From 2c48599bcbdb7a4394daec68498cf36537a9dffd Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 9 Jun 2023 14:34:50 +0100 Subject: [PATCH 7/7] docs: doc comments for http registry --- src/cargo/sources/registry/http_remote.rs | 49 ++++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/cargo/sources/registry/http_remote.rs b/src/cargo/sources/registry/http_remote.rs index 7e1f2a58740..55fe1fd454c 100644 --- a/src/cargo/sources/registry/http_remote.rs +++ b/src/cargo/sources/registry/http_remote.rs @@ -1,6 +1,4 @@ -//! Access to a HTTP-based crate registry. -//! -//! See [`HttpRegistry`] for details. +//! Access to a HTTP-based crate registry. See [`HttpRegistry`] for details. use crate::core::{PackageId, SourceId}; use crate::ops::{self}; @@ -52,8 +50,15 @@ const UNKNOWN: &'static str = "Unknown"; /// /// [RFC 2789]: https://github.com/rust-lang/rfcs/pull/2789 pub struct HttpRegistry<'cfg> { + /// Path to the registry index (`$CARGO_HOME/registry/index/$REG-HASH`). + /// + /// To be fair, `HttpRegistry` doesn't store the registry index it + /// downloads on the file system, but other cached data like registry + /// configuration could be stored here. index_path: Filesystem, + /// Path to the cache of `.crate` files (`$CARGO_HOME/registry/cache/$REG-HASH`). cache_path: Filesystem, + /// The unique identifier of this registry source. source_id: SourceId, config: &'cfg Config, @@ -95,20 +100,20 @@ pub struct HttpRegistry<'cfg> { quiet: bool, } -/// Helper for downloading crates. +/// State for currently pending index file downloads. struct Downloads<'cfg> { /// When a download is started, it is added to this map. The key is a - /// "token" (see `Download::token`). It is removed once the download is + /// "token" (see [`Download::token`]). It is removed once the download is /// finished. pending: HashMap, EasyHandle)>, /// Set of paths currently being downloaded. - /// This should stay in sync with `pending`. + /// This should stay in sync with the `pending` field. pending_paths: HashSet, /// Downloads that have failed and are waiting to retry again later. sleeping: SleepTracker<(Download<'cfg>, Easy)>, /// The final result of each download. results: HashMap>, - /// The next ID to use for creating a token (see `Download::token`). + /// The next ID to use for creating a token (see [`Download::token`]). next: usize, /// Progress bar. progress: RefCell>>, @@ -119,9 +124,10 @@ struct Downloads<'cfg> { blocking_calls: usize, } +/// Represents a single index file download, including its progress and retry. struct Download<'cfg> { - /// The token for this download, used as the key of the `Downloads::pending` map - /// and stored in `EasyHandle` as well. + /// The token for this download, used as the key of the + /// [`Downloads::pending`] map and stored in [`EasyHandle`] as well. token: usize, /// The path of the package that we're downloading. @@ -137,14 +143,17 @@ struct Download<'cfg> { retry: Retry<'cfg>, } +/// HTTPS headers [`HttpRegistry`] cares about. #[derive(Default)] struct Headers { last_modified: Option, etag: Option, www_authenticate: Vec, + /// We don't care about these headers. Put them here for debugging purpose. others: Vec, } +/// HTTP status code [`HttpRegistry`] cares about. enum StatusCode { Success, NotModified, @@ -152,6 +161,10 @@ enum StatusCode { Unauthorized, } +/// Represents a complete [`Download`] from an HTTP request. +/// +/// Usually it is constructed in [`HttpRegistry::handle_completed_downloads`], +/// and then returns to the caller of [`HttpRegistry::load()`]. struct CompletedDownload { response_code: StatusCode, data: Vec, @@ -159,6 +172,10 @@ struct CompletedDownload { } impl<'cfg> HttpRegistry<'cfg> { + /// Creates a HTTP-rebased remote registry for `source_id`. + /// + /// * `name` --- Name of a path segment where `.crate` tarballs and the + /// registry index are stored. Expect to be unique. pub fn new( source_id: SourceId, config: &'cfg Config, @@ -208,6 +225,7 @@ impl<'cfg> HttpRegistry<'cfg> { }) } + /// Splits HTTP `HEADER: VALUE` to a tuple. fn handle_http_header(buf: &[u8]) -> Option<(&str, &str)> { if buf.is_empty() { return None; @@ -222,6 +240,9 @@ impl<'cfg> HttpRegistry<'cfg> { Some((tag, value)) } + /// Setup the necessary works before the first fetch gets started. + /// + /// This is a no-op if called more than one time. fn start_fetch(&mut self) -> CargoResult<()> { if self.fetch_started { // We only need to run the setup code once. @@ -249,6 +270,8 @@ impl<'cfg> HttpRegistry<'cfg> { Ok(()) } + /// Checks the results inside the [`HttpRegistry::multi`] handle, and + /// updates relevant state in [`HttpRegistry::downloads`] accordingly. fn handle_completed_downloads(&mut self) -> CargoResult<()> { assert_eq!( self.downloads.pending.len(), @@ -322,11 +345,15 @@ impl<'cfg> HttpRegistry<'cfg> { Ok(()) } + /// Constructs the full URL to download a index file. fn full_url(&self, path: &Path) -> String { // self.url always ends with a slash. format!("{}{}", self.url, path.display()) } + /// Check if an index file of `path` is up-to-date. + /// + /// The `path` argument is the same as in [`RegistryData::load`]. fn is_fresh(&self, path: &Path) -> bool { if !self.requested_update { trace!( @@ -373,7 +400,7 @@ impl<'cfg> HttpRegistry<'cfg> { Ok(self.registry_config.as_ref()) } - /// Get the registry configuration. + /// Get the registry configuration from either cache or remote. fn config(&mut self) -> Poll> { debug!("loading config"); let index_path = self.assert_index_locked(&self.index_path); @@ -405,6 +432,7 @@ impl<'cfg> HttpRegistry<'cfg> { } } + /// Moves failed [`Download`]s that are ready to retry to the pending queue. fn add_sleepers(&mut self) -> CargoResult<()> { for (dl, handle) in self.downloads.sleeping.to_retry() { let mut handle = self.multi.add(handle)?; @@ -790,6 +818,7 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> { } impl<'cfg> Downloads<'cfg> { + /// Updates the state of the progress bar for downloads. fn tick(&self) -> CargoResult<()> { let mut progress = self.progress.borrow_mut(); let Some(progress) = progress.as_mut() else { return Ok(()); };