1 use crate::core
::compiler
::{BuildConfig, CompileMode, RustcTargetData}
;
2 use crate::core
::{PackageSet, Resolve, Workspace}
;
4 use crate::util
::CargoResult
;
5 use crate::util
::Config
;
6 use std
::collections
::HashSet
;
8 pub struct FetchOptions
<'a
> {
9 pub config
: &'a Config
,
10 /// The target arch triple to fetch dependencies for
11 pub targets
: Vec
<String
>,
14 /// Executes `cargo fetch`.
17 options
: &FetchOptions
<'a
>,
18 ) -> CargoResult
<(Resolve
, PackageSet
<'a
>)> {
20 let (packages
, resolve
) = ops
::resolve_ws(ws
)?
;
23 let config
= ws
.config();
24 let build_config
= BuildConfig
::new(config
, jobs
, &options
.targets
, CompileMode
::Build
)?
;
25 let data
= RustcTargetData
::new(ws
, &build_config
.requested_kinds
)?
;
26 let mut fetched_packages
= HashSet
::new();
27 let mut deps_to_fetch
= ws
.members().map(|p
| p
.package_id()).collect
::<Vec
<_
>>();
28 let mut to_download
= Vec
::new();
30 while let Some(id
) = deps_to_fetch
.pop() {
31 if !fetched_packages
.insert(id
) {
38 .filter(|&(_id
, deps
)| {
40 // If no target was specified then all dependencies are
42 if options
.targets
.is_empty() {
46 // Otherwise we only download this dependency if any of the
47 // requested platforms would match this dependency. Note
48 // that this is a bit lossy because not all dependencies are
49 // always compiled for all platforms, but it should be
50 // "close enough" for now.
54 .any(|kind
| data
.dep_platform_activated(d
, *kind
))
57 .map(|(id
, _deps
)| id
);
58 deps_to_fetch
.extend(deps
);
60 packages
.get_many(to_download
)?
;
62 Ok((resolve
, packages
))