1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::collections::{HashMap, HashSet};
use core::{Package, PackageId, SourceId};
use core::registry::PackageRegistry;
use core::resolver::{self, Resolve, Method};
use ops;
use util::CargoResult;
pub fn resolve_pkg(registry: &mut PackageRegistry, package: &Package)
-> CargoResult<Resolve> {
let prev = try!(ops::load_pkg_lockfile(package));
let resolve = try!(resolve_with_previous(registry, package,
Method::Everything,
prev.as_ref(), None));
if package.package_id().source_id().is_path() {
try!(ops::write_pkg_lockfile(package, &resolve));
}
Ok(resolve)
}
pub fn resolve_with_previous<'a>(registry: &mut PackageRegistry,
package: &Package,
method: Method,
previous: Option<&'a Resolve>,
to_avoid: Option<&HashSet<&'a PackageId>>)
-> CargoResult<Resolve> {
try!(registry.add_sources(&[package.package_id().source_id()
.clone()]));
let mut to_avoid_sources = HashSet::new();
match to_avoid {
Some(set) => {
for package_id in set.iter() {
let source = package_id.source_id();
if !source.is_registry() {
to_avoid_sources.insert(source);
}
}
}
None => {}
}
let summary = package.summary().clone();
let summary = match previous {
Some(r) => {
for node in r.iter().filter(|p| keep(p, to_avoid, &to_avoid_sources)) {
let deps = r.deps(node).into_iter().flat_map(|i| i)
.filter(|p| keep(p, to_avoid, &to_avoid_sources))
.map(|p| p.clone()).collect();
registry.register_lock(node.clone(), deps);
}
let map = r.deps(r.root()).into_iter().flat_map(|i| i).filter(|p| {
keep(p, to_avoid, &to_avoid_sources)
}).map(|d| {
(d.name(), d)
}).collect::<HashMap<_, _>>();
summary.map_dependencies(|d| {
match map.get(d.name()) {
Some(&lock) if d.matches_id(lock) => d.lock_to(lock),
_ => d,
}
})
}
None => summary,
};
let mut resolved = try!(resolver::resolve(&summary, &method, registry));
match previous {
Some(r) => resolved.copy_metadata(r),
None => {}
}
return Ok(resolved);
fn keep<'a>(p: &&'a PackageId,
to_avoid_packages: Option<&HashSet<&'a PackageId>>,
to_avoid_sources: &HashSet<&'a SourceId>)
-> bool {
!to_avoid_sources.contains(&p.source_id()) && match to_avoid_packages {
Some(set) => !set.contains(p),
None => true,
}
}
}