#
cargo/ops/
cargo_fetch.rs

    1use crate::core::compiler::BuildConfig;
    2use crate::core::compiler::RustcTargetData;
    3use crate::core::compiler::UserIntent;
    4use crate::core::compiler::standard_lib;
    5use crate::core::{PackageSet, Resolve, Workspace};
    6use crate::ops;
    7use crate::util::CargoResult;
    8use crate::util::GlobalContext;
    9use crate::util::context::JobsConfig;
    10use std::collections::HashSet;
    11
    12pub struct FetchOptions<'a> {
    13    pub gctx: &'a GlobalContext,
    14    /// The target arch triple to fetch dependencies for
    15    pub targets: Vec<String>,
    16}
    17
    18/// Executes `cargo fetch`.
    19pub fn fetch<'a>(
    20    ws: &Workspace<'a>,
    21    options: &FetchOptions<'a>,
    22) -> CargoResult<(Resolve, PackageSet<'a>)> {
    23    ws.emit_warnings()?;
    24    let dry_run = false;
    25    let (mut packages, resolve) = ops::resolve_ws(ws, dry_run)?;
    26
    27    let jobs = Some(JobsConfig::Integer(1));
    28    let keep_going = false;
    29    let gctx = ws.gctx();
    30    let build_config =
    31        BuildConfig::new(gctx, jobs, keep_going, &options.targets, UserIntent::Build)?;
    32    let mut data = RustcTargetData::new(ws, &build_config.requested_kinds)?;
    33    let mut fetched_packages = HashSet::new();
    34    let mut deps_to_fetch = ws.members().map(|p| p.package_id()).collect::<Vec<_>>();
    35    let mut to_download = Vec::new();
    36
    37    while let Some(id) = deps_to_fetch.pop() {
    38        if !fetched_packages.insert(id) {
    39            continue;
    40        }
    41
    42        to_download.push(id);
    43        let deps = resolve
    44            .deps(id)
    45            .filter(|&(_id, deps)| {
    46                deps.iter().any(|d| {
    47                    // If no target was specified then all dependencies are
    48                    // fetched.
    49                    if options.targets.is_empty() {
    50                        return true;
    51                    }
    52
    53                    // Otherwise we only download this dependency if any of the
    54                    // requested platforms would match this dependency. Note
    55                    // that this is a bit lossy because not all dependencies are
    56                    // always compiled for all platforms, but it should be
    57                    // "close enough" for now.
    58                    build_config
    59                        .requested_kinds
    60                        .iter()
    61                        .any(|kind| data.dep_platform_activated(d, *kind))
    62                })
    63            })
    64            .map(|(id, _deps)| id);
    65        deps_to_fetch.extend(deps);
    66    }
    67
    68    // If -Zbuild-std was passed, download dependencies for the standard library.
    69    if let Some(crates) = &gctx.cli_unstable().build_std {
    70        let (std_package_set, _, _) = standard_lib::resolve_std(
    71            ws,
    72            &mut data,
    73            &build_config,
    74            crates,
    75            &build_config.requested_kinds,
    76        )?;
    77        packages.add_set(std_package_set);
    78    }
    79
    80    packages.get_many(to_download)?;
    81    crate::core::gc::auto_gc(gctx);
    82
    83    Ok((resolve, packages))
    84}