]>
Commit | Line | Data |
---|---|---|
c30ab7b3 SL |
1 | use std::collections::HashMap; |
2 | use std::process::Command; | |
3 | use std::path::PathBuf; | |
94b46f34 | 4 | use std::collections::HashSet; |
c30ab7b3 SL |
5 | |
6 | use build_helper::output; | |
48663c56 | 7 | use serde::Deserialize; |
3b2f2976 | 8 | use serde_json; |
c30ab7b3 | 9 | |
0731742a XL |
10 | use crate::{Build, Crate}; |
11 | use crate::cache::INTERNER; | |
c30ab7b3 | 12 | |
3b2f2976 | 13 | #[derive(Deserialize)] |
c30ab7b3 SL |
14 | struct Output { |
15 | packages: Vec<Package>, | |
16 | resolve: Resolve, | |
17 | } | |
18 | ||
3b2f2976 | 19 | #[derive(Deserialize)] |
c30ab7b3 SL |
20 | struct Package { |
21 | id: String, | |
22 | name: String, | |
23 | source: Option<String>, | |
24 | manifest_path: String, | |
25 | } | |
26 | ||
3b2f2976 | 27 | #[derive(Deserialize)] |
c30ab7b3 SL |
28 | struct Resolve { |
29 | nodes: Vec<ResolveNode>, | |
30 | } | |
31 | ||
3b2f2976 | 32 | #[derive(Deserialize)] |
c30ab7b3 SL |
33 | struct ResolveNode { |
34 | id: String, | |
35 | dependencies: Vec<String>, | |
36 | } | |
37 | ||
38 | pub fn build(build: &mut Build) { | |
94b46f34 XL |
39 | let mut resolves = Vec::new(); |
40 | build_krate(&build.std_features(), build, &mut resolves, "src/libstd"); | |
41 | build_krate("", build, &mut resolves, "src/libtest"); | |
42 | build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc"); | |
43 | ||
8faf50e0 | 44 | let mut id2name = HashMap::with_capacity(build.crates.len()); |
94b46f34 XL |
45 | for (name, krate) in build.crates.iter() { |
46 | id2name.insert(krate.id.clone(), name.clone()); | |
47 | } | |
48 | ||
49 | for node in resolves { | |
50 | let name = match id2name.get(&node.id) { | |
51 | Some(name) => name, | |
52 | None => continue, | |
53 | }; | |
54 | ||
55 | let krate = build.crates.get_mut(name).unwrap(); | |
56 | for dep in node.dependencies.iter() { | |
57 | let dep = match id2name.get(dep) { | |
58 | Some(dep) => dep, | |
59 | None => continue, | |
60 | }; | |
61 | krate.deps.insert(*dep); | |
62 | } | |
63 | } | |
c30ab7b3 SL |
64 | } |
65 | ||
94b46f34 | 66 | fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec<ResolveNode>, krate: &str) { |
c30ab7b3 SL |
67 | // Run `cargo metadata` to figure out what crates we're testing. |
68 | // | |
69 | // Down below we're going to call `cargo test`, but to test the right set | |
70 | // of packages we're going to have to know what `-p` arguments to pass it | |
71 | // to know what crates to test. Here we run `cargo metadata` to learn about | |
72 | // the dependency graph and what `-p` arguments there are. | |
041b39d2 | 73 | let mut cargo = Command::new(&build.initial_cargo); |
c30ab7b3 | 74 | cargo.arg("metadata") |
7cac9316 | 75 | .arg("--format-version").arg("1") |
94b46f34 | 76 | .arg("--features").arg(features) |
c30ab7b3 SL |
77 | .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml")); |
78 | let output = output(&mut cargo); | |
3b2f2976 | 79 | let output: Output = serde_json::from_str(&output).unwrap(); |
c30ab7b3 SL |
80 | for package in output.packages { |
81 | if package.source.is_none() { | |
3b2f2976 | 82 | let name = INTERNER.intern_string(package.name); |
c30ab7b3 SL |
83 | let mut path = PathBuf::from(package.manifest_path); |
84 | path.pop(); | |
3b2f2976 | 85 | build.crates.insert(name, Crate { |
3b2f2976 | 86 | name, |
94b46f34 XL |
87 | id: package.id, |
88 | deps: HashSet::new(), | |
3b2f2976 | 89 | path, |
c30ab7b3 SL |
90 | }); |
91 | } | |
92 | } | |
94b46f34 | 93 | resolves.extend(output.resolve.nodes); |
c30ab7b3 | 94 | } |