#
cargo/ops/
cargo_fetch.rs

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