1use crate::core::compiler::{BuildConfig, CompileMode, TargetInfo};
2use crate::core::{PackageSet, Resolve, Workspace};
3use crate::ops;
4use crate::util::CargoResult;
5use crate::util::Config;
6use std::collections::HashSet;
7
8pub struct FetchOptions<'a> {
9 pub config: &'a Config,
10 pub target: Option<String>,
12}
13
14pub fn fetch<'a>(
16 ws: &Workspace<'a>,
17 options: &FetchOptions<'a>,
18) -> CargoResult<(Resolve, PackageSet<'a>)> {
19 ws.emit_warnings()?;
20 let (packages, resolve) = ops::resolve_ws(ws)?;
21
22 let jobs = Some(1);
23 let config = ws.config();
24 let build_config = BuildConfig::new(config, jobs, &options.target, CompileMode::Build)?;
25 let rustc = config.load_global_rustc(Some(ws))?;
26 let target_info = TargetInfo::new(
27 config,
28 build_config.requested_kind,
29 &rustc,
30 build_config.requested_kind,
31 )?;
32 let mut fetched_packages = HashSet::new();
33 let mut deps_to_fetch = ws.members().map(|p| p.package_id()).collect::<Vec<_>>();
34 let mut to_download = Vec::new();
35
36 while let Some(id) = deps_to_fetch.pop() {
37 if !fetched_packages.insert(id) {
38 continue;
39 }
40
41 to_download.push(id);
42 let deps = resolve
43 .deps(id)
44 .filter(|&(_id, deps)| {
45 deps.iter().any(|d| {
46 let target = match options.target {
49 Some(ref t) => t,
50 None => return true,
51 };
52 let platform = match d.platform() {
56 Some(p) => p,
57 None => return true,
58 };
59 platform.matches(target, target_info.cfg())
60 })
61 })
62 .map(|(id, _deps)| id);
63 deps_to_fetch.extend(deps);
64 }
65 packages.get_many(to_download)?;
66
67 Ok((resolve, packages))
68}