bootstrap: treat src/tools/cargo as a workspace member
We remove `src/tools/cargo` from rust-lang/rust root workspace, but some underlying mechanism still needs it to be a member. for example, `./x.py doc`. This little hack make cargo's metadata available by invoking an extra `cargo metadata` for cargo the package itself. Co-authored-by: Scott Schafer <schaferjscott@gmail.com> Co-authored-by: Eric Huss <eric@huss.org>
This commit is contained in:
parent
4c777710c6
commit
82950f6895
@ -7,12 +7,16 @@
|
||||
use crate::util::output;
|
||||
use crate::{Build, Crate};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// For more information, see the output of
|
||||
/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Output {
|
||||
packages: Vec<Package>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// For more information, see the output of
|
||||
/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Package {
|
||||
name: String,
|
||||
source: Option<String>,
|
||||
@ -20,25 +24,18 @@ struct Package {
|
||||
dependencies: Vec<Dependency>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// For more information, see the output of
|
||||
/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Dependency {
|
||||
name: String,
|
||||
source: Option<String>,
|
||||
}
|
||||
|
||||
/// Collects and stores package metadata of each workspace members into `build`,
|
||||
/// by executing `cargo metadata` commands.
|
||||
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 {
|
||||
for package in workspace_members(build) {
|
||||
if package.source.is_none() {
|
||||
let name = INTERNER.intern_string(package.name);
|
||||
let mut path = PathBuf::from(package.manifest_path);
|
||||
@ -57,3 +54,35 @@ pub fn build(build: &mut Build) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Invokes `cargo metadata` to get package metadata of each workspace member.
|
||||
///
|
||||
/// Note that `src/tools/cargo` is no longer a workspace member but we still
|
||||
/// treat it as one here, by invoking an additional `cargo metadata` command.
|
||||
fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
|
||||
let cmd_metadata = |manifest_path| {
|
||||
let mut cargo = Command::new(&build.initial_cargo);
|
||||
cargo
|
||||
.arg("metadata")
|
||||
.arg("--format-version")
|
||||
.arg("1")
|
||||
.arg("--no-deps")
|
||||
.arg("--manifest-path")
|
||||
.arg(manifest_path);
|
||||
cargo
|
||||
};
|
||||
|
||||
// Collects `metadata.packages` from the root workspace.
|
||||
let root_manifest_path = build.src.join("Cargo.toml");
|
||||
let root_output = output(&mut cmd_metadata(&root_manifest_path));
|
||||
let Output { packages, .. } = serde_json::from_str(&root_output).unwrap();
|
||||
|
||||
// Collects `metadata.packages` from src/tools/cargo separately.
|
||||
let cargo_manifest_path = build.src.join("src/tools/cargo/Cargo.toml");
|
||||
let cargo_output = output(&mut cmd_metadata(&cargo_manifest_path));
|
||||
let Output { packages: cargo_packages, .. } = serde_json::from_str(&cargo_output).unwrap();
|
||||
|
||||
// We only care about the root package from `src/tool/cargo` workspace.
|
||||
let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter();
|
||||
packages.into_iter().chain(cargo_package)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user