bootstrap/core/
metadata.rs
1use std::collections::BTreeMap;
2use std::path::PathBuf;
3
4use serde_derive::Deserialize;
5
6use crate::utils::exec::command;
7use crate::{Build, Crate, t};
8
9#[derive(Debug, Deserialize)]
12struct Output {
13 packages: Vec<Package>,
14}
15
16#[derive(Debug, Deserialize)]
19struct Package {
20 name: String,
21 source: Option<String>,
22 manifest_path: String,
23 dependencies: Vec<Dependency>,
24 targets: Vec<Target>,
25 features: BTreeMap<String, Vec<String>>,
26}
27
28#[derive(Debug, Deserialize)]
31struct Dependency {
32 name: String,
33 source: Option<String>,
34}
35
36#[derive(Debug, Deserialize)]
37struct Target {
38 kind: Vec<String>,
39}
40
41pub fn build(build: &mut Build) {
44 for package in workspace_members(build) {
45 if package.source.is_none() {
46 let name = package.name;
47 let mut path = PathBuf::from(package.manifest_path);
48 path.pop();
49 let deps = package
50 .dependencies
51 .into_iter()
52 .filter(|dep| dep.source.is_none())
53 .map(|dep| dep.name)
54 .collect();
55 let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib"));
56 let krate = Crate {
57 name: name.clone(),
58 deps,
59 path,
60 has_lib,
61 features: package.features.keys().cloned().collect(),
62 };
63 let relative_path = krate.local_path(build);
64 build.crates.insert(name.clone(), krate);
65 let existing_path = build.crate_paths.insert(relative_path, name);
66 assert!(
67 existing_path.is_none(),
68 "multiple crates with the same path: {}",
69 existing_path.unwrap()
70 );
71 }
72 }
73}
74
75fn workspace_members(build: &Build) -> Vec<Package> {
80 let collect_metadata = |manifest_path| {
81 let mut cargo = command(&build.initial_cargo);
82 cargo
83 .env("RUSTC_BOOTSTRAP", "1")
86 .arg("metadata")
87 .arg("--format-version")
88 .arg("1")
89 .arg("--no-deps")
90 .arg("--manifest-path")
91 .arg(build.src.join(manifest_path));
92 let metadata_output = cargo.run_always().run_capture_stdout(build).stdout();
93 let Output { packages, .. } = t!(serde_json::from_str(&metadata_output));
94 packages
95 };
96
97 let mut packages = vec![];
99 packages.extend(collect_metadata("Cargo.toml"));
100 packages.extend(collect_metadata("library/Cargo.toml"));
101 packages
102}