Skip to content

Commit

Permalink
Auto merge of #12192 - weihanglo:source-doc, r=epage
Browse files Browse the repository at this point in the history
docs: add doc comments for git source and friends
  • Loading branch information
bors committed May 28, 2023
2 parents 068e549 + 9a29b8b commit 6956c04
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 47 deletions.
3 changes: 3 additions & 0 deletions src/cargo/sources/git/known_hosts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! SSH host key validation support.
//!
//! The only public item in this module is [`certificate_check`],
//! which provides a callback to [`git2::RemoteCallbacks::certificate_check`].
//!
//! A primary goal with this implementation is to provide user-friendly error
//! messages, guiding them to understand the issue and how to resolve it.
//!
Expand Down
10 changes: 10 additions & 0 deletions src/cargo/sources/git/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
//! Home of the [`GitSource`].
//!
//! Apparently, the most important type in this module is [`GitSource`].
//! [`utils`] provides libgit2 utilities like fetch and checkout, whereas
//! [`oxide`] is the couterpart for gitoxide integration. [`known_hosts`]
//! is the mitigation of [CVE-2022-46176].
//!
//! [CVE-2022-46176]: https://blog.rust-lang.org/2023/01/10/cve-2022-46176.html

pub use self::source::GitSource;
pub use self::utils::{fetch, GitCheckout, GitDatabase, GitRemote};
mod known_hosts;
mod oxide;
mod source;
mod utils;

/// For `-Zgitoxide` integration.
pub mod fetch {
use crate::core::features::GitoxideFeatures;
use crate::Config;
Expand Down
2 changes: 2 additions & 0 deletions src/cargo/sources/git/oxide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ pub fn cargo_config_to_gitoxide_overrides(config: &Config) -> CargoResult<Vec<BS
Ok(values)
}

/// Reinitializes a given Git repository. This is useful when a Git repoistory
/// seems corrupted and we want to start over.
pub fn reinitialize(git_dir: &Path) -> CargoResult<()> {
fn init(path: &Path, bare: bool) -> CargoResult<()> {
let mut opts = git2::RepositoryInitOptions::new();
Expand Down
70 changes: 66 additions & 4 deletions src/cargo/sources/git/source.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! See [GitSource].

use crate::core::source::{MaybePackage, QueryKind, Source, SourceId};
use crate::core::GitReference;
use crate::core::{Dependency, Package, PackageId, Summary};
Expand All @@ -13,18 +15,71 @@ use std::fmt::{self, Debug, Formatter};
use std::task::Poll;
use url::Url;

/// `GitSource` contains one or more packages gathering from a Git repository.
/// Under the hood it uses [`PathSource`] to discover packages inside the
/// repository.
///
/// ## Filesystem layout
///
/// During a successful `GitSource` download, at least two Git repositories are
/// created: one is the shared Git database of this remote, and the other is the
/// Git checkout to a specific revision, which contains the actual files to be
/// compiled. Multiple checkouts can be cloned from a single Git database.
///
/// Those repositories are located at Cargo's Git cache directory
/// `$CARGO_HOME/git`. The file tree of the cache directory roughly looks like:
///
/// ```text
/// $CARGO_HOME/git/
/// ├── checkouts/
/// │ ├── gimli-a0d193bd15a5ed96/
/// │ │ ├── 8e73ef0/ # Git short ID for a certain revision
/// │ │ ├── a2a4b78/
/// │ │ └── e33d1ac/
/// │ ├── log-c58e1db3de7c154d-shallow/
/// │ │ └── 11eda98/
/// └── db/
/// ├── gimli-a0d193bd15a5ed96/
/// └── log-c58e1db3de7c154d-shallow/
/// ```
///
/// For more on Git cache directory, see ["Cargo Home"] in The Cargo Book.
///
/// For more on the directory format `<pkg>-<hash>[-shallow]`, see [`ident`]
/// and [`ident_shallow`].
///
/// ## Locked to a revision
///
/// Once a `GitSource` is fetched, it will resolve to a specific commit revision.
/// This is often mentioned as "locked revision" (`locked_rev`) throughout the
/// codebase. The revision is written into `Cargo.lock`. This is essential since
/// we want to ensure a package can compiles with the same set of files when
/// a `Cargo.lock` is present. With the `locked_rev` provided, `GitSource` can
/// precisely fetch the same revision from the Git repository.
///
/// ["Cargo Home"]: https://doc.rust-lang.org/nightly/cargo/guide/cargo-home.html#directories
pub struct GitSource<'cfg> {
/// The git remote which we're going to fetch from.
remote: GitRemote,
/// The Git reference from the manifest file.
manifest_reference: GitReference,
/// The revision which a git source is locked to.
/// This is expected to be set after the Git repository is fetched.
locked_rev: Option<git2::Oid>,
/// The unique identifier of this source.
source_id: SourceId,
/// The underlying path source to discover packages inside the Git repository.
path_source: Option<PathSource<'cfg>>,
/// The identifer of this source for Cargo's Git cache directory.
/// See [`ident`] for more.
ident: String,
config: &'cfg Config,
/// Disables status messages.
quiet: bool,
}

impl<'cfg> GitSource<'cfg> {
/// Creates a git source for the given [`SourceId`].
pub fn new(source_id: SourceId, config: &'cfg Config) -> CargoResult<GitSource<'cfg>> {
assert!(source_id.is_git(), "id is not git, id={}", source_id);

Expand Down Expand Up @@ -59,10 +114,14 @@ impl<'cfg> GitSource<'cfg> {
Ok(source)
}

/// Gets the remote repository URL.
pub fn url(&self) -> &Url {
self.remote.url()
}

/// Returns the packages discovered by this source. It may fetch the Git
/// repository as well as walk the filesystem if package informations
/// haven't yet updated.
pub fn read_packages(&mut self) -> CargoResult<Vec<Package>> {
if self.path_source.is_none() {
self.invalidate_cache();
Expand All @@ -72,7 +131,8 @@ impl<'cfg> GitSource<'cfg> {
}
}

/// Create an identifier from a URL, essentially turning `proto://host/path/repo` into `repo-<hash-of-url>`.
/// Create an identifier from a URL,
/// essentially turning `proto://host/path/repo` into `repo-<hash-of-url>`.
fn ident(id: &SourceId) -> String {
let ident = id
.canonical_url()
Expand All @@ -86,10 +146,12 @@ fn ident(id: &SourceId) -> String {
format!("{}-{}", ident, short_hash(id.canonical_url()))
}

/// Like `ident()`, but appends `-shallow` to it, turning `proto://host/path/repo` into `repo-<hash-of-url>-shallow`.
/// Like [`ident()`], but appends `-shallow` to it, turning
/// `proto://host/path/repo` into `repo-<hash-of-url>-shallow`.
///
/// It's important to separate shallow from non-shallow clones for reasons of backwards compatibility - older
/// cargo's aren't necessarily handling shallow clones correctly.
/// It's important to separate shallow from non-shallow clones for reasons of
/// backwards compatibility --- older cargo's aren't necessarily handling
/// shallow clones correctly.
fn ident_shallow(id: &SourceId, is_shallow: bool) -> String {
let mut ident = ident(id);
if is_shallow {
Expand Down
Loading

0 comments on commit 6956c04

Please sign in to comment.