diff options
| author | Weihang Lo <me@weihanglo.tw> | 2023-03-14 10:23:14 +0000 |
|---|---|---|
| committer | Weihang Lo <me@weihanglo.tw> | 2023-04-16 19:32:20 +0100 |
| commit | 82950f6895638b7fe5e80a961cb03fca27436629 (patch) | |
| tree | f55d08ac181dba741ac74984c4ed711b5698519a /src/bootstrap | |
| parent | 4c777710c6f5996e0967fe5b9d2924684c646626 (diff) | |
| download | rust-82950f6895638b7fe5e80a961cb03fca27436629.tar.gz rust-82950f6895638b7fe5e80a961cb03fca27436629.zip | |
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>
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/metadata.rs | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index bba4d65e8c3..597aefadcfe 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -7,12 +7,16 @@ use crate::cache::INTERNER; 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) +} |
