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 pub targets: Vec<String>,
14}
15
16pub 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 options.targets.is_empty() {
48 return true;
49 }
50
51 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 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}