summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/metadata.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/metadata.rs')
-rw-r--r--src/bootstrap/metadata.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs
new file mode 100644
index 000000000..e193e70a0
--- /dev/null
+++ b/src/bootstrap/metadata.rs
@@ -0,0 +1,59 @@
+use std::path::PathBuf;
+use std::process::Command;
+
+use serde::Deserialize;
+
+use crate::cache::INTERNER;
+use crate::util::output;
+use crate::{Build, Crate};
+
+#[derive(Deserialize)]
+struct Output {
+ packages: Vec<Package>,
+}
+
+#[derive(Deserialize)]
+struct Package {
+ name: String,
+ source: Option<String>,
+ manifest_path: String,
+ dependencies: Vec<Dependency>,
+}
+
+#[derive(Deserialize)]
+struct Dependency {
+ name: String,
+ source: Option<String>,
+}
+
+pub fn build(build: &mut Build) {
+ // Run `cargo metadata` to figure out what crates we're testing.
+ let mut cargo = Command::new(&build.initial_cargo);
+ cargo
+ .arg("metadata")
+ .arg("--format-version")
+ .arg("1")
+ .arg("--no-deps")
+ .arg("--manifest-path")
+ .arg(build.src.join("Cargo.toml"));
+ let output = output(&mut cargo);
+ let output: Output = serde_json::from_str(&output).unwrap();
+ for package in output.packages {
+ if package.source.is_none() {
+ let name = INTERNER.intern_string(package.name);
+ let mut path = PathBuf::from(package.manifest_path);
+ path.pop();
+ let deps = package
+ .dependencies
+ .into_iter()
+ .filter(|dep| dep.source.is_none())
+ .map(|dep| INTERNER.intern_string(dep.name))
+ .collect();
+ let krate = Crate { name, deps, path };
+ let relative_path = krate.local_path(build);
+ build.crates.insert(name, krate);
+ let existing_path = build.crate_paths.insert(relative_path, name);
+ assert!(existing_path.is_none(), "multiple crates with the same path");
+ }
+ }
+}