@@ -17,25 +17,29 @@ struct Output {
1717/// For more information, see the output of
1818/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
1919#[ derive( Debug , Deserialize ) ]
20- struct Package {
21- name : String ,
22- source : Option < String > ,
23- manifest_path : String ,
24- dependencies : Vec < Dependency > ,
25- targets : Vec < Target > ,
20+ pub ( crate ) struct Package {
21+ pub ( crate ) name : String ,
22+ pub ( crate ) source : Option < String > ,
23+ pub ( crate ) manifest_path : String ,
24+ pub ( crate ) dependencies : Vec < Dependency > ,
25+ pub ( crate ) targets : Vec < Target > ,
2626}
2727
2828/// For more information, see the output of
2929/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
30- #[ derive( Debug , Deserialize ) ]
31- struct Dependency {
32- name : String ,
33- source : Option < String > ,
30+ #[ derive( Debug , Deserialize , PartialEq ) ]
31+ pub ( crate ) struct Dependency {
32+ pub ( crate ) name : String ,
33+ pub ( crate ) source : Option < String > ,
3434}
3535
3636#[ derive( Debug , Deserialize ) ]
37- struct Target {
38- kind : Vec < String > ,
37+ pub ( crate ) struct Target {
38+ pub ( crate ) name : String ,
39+ pub ( crate ) kind : Vec < String > ,
40+ pub ( crate ) crate_types : Vec < String > ,
41+ pub ( crate ) src_path : String ,
42+ pub ( crate ) edition : String ,
3943}
4044
4145/// Collects and stores package metadata of each workspace members into `build`,
@@ -70,7 +74,7 @@ pub fn build(build: &mut Build) {
7074///
7175/// Note that `src/tools/cargo` is no longer a workspace member but we still
7276/// treat it as one here, by invoking an additional `cargo metadata` command.
73- fn workspace_members ( build : & Build ) -> impl Iterator < Item = Package > {
77+ pub ( crate ) fn workspace_members ( build : & Build ) -> impl Iterator < Item = Package > {
7478 let collect_metadata = |manifest_path| {
7579 let mut cargo = Command :: new ( & build. initial_cargo ) ;
7680 cargo
@@ -99,3 +103,33 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
99103
100104 packages. into_iter ( ) . chain ( cargo_package) . chain ( ra_packages) . chain ( bootstrap_packages)
101105}
106+
107+ /// Invokes `cargo metadata` to get package metadata of whole workspace including the dependencies.
108+ pub ( crate ) fn project_metadata ( build : & Build ) -> impl Iterator < Item = Package > {
109+ let collect_metadata = |manifest_path| {
110+ let mut cargo = Command :: new ( & build. initial_cargo ) ;
111+ cargo
112+ // Will read the libstd Cargo.toml
113+ // which uses the unstable `public-dependency` feature.
114+ . env ( "RUSTC_BOOTSTRAP" , "1" )
115+ . arg ( "metadata" )
116+ . arg ( "--format-version" )
117+ . arg ( "1" )
118+ . arg ( "--manifest-path" )
119+ . arg ( build. src . join ( manifest_path) ) ;
120+ let metadata_output = output ( & mut cargo) ;
121+ let Output { packages, .. } = t ! ( serde_json:: from_str( & metadata_output) ) ;
122+ packages
123+ } ;
124+
125+ // Collects `metadata.packages` from all workspaces.
126+ let packages = collect_metadata ( "Cargo.toml" ) ;
127+ let cargo_packages = collect_metadata ( "src/tools/cargo/Cargo.toml" ) ;
128+ let ra_packages = collect_metadata ( "src/tools/rust-analyzer/Cargo.toml" ) ;
129+ let bootstrap_packages = collect_metadata ( "src/bootstrap/Cargo.toml" ) ;
130+
131+ // We only care about the root package from `src/tool/cargo` workspace.
132+ let cargo_package = cargo_packages. into_iter ( ) . find ( |pkg| pkg. name == "cargo" ) . into_iter ( ) ;
133+
134+ packages. into_iter ( ) . chain ( cargo_package) . chain ( ra_packages) . chain ( bootstrap_packages)
135+ }
0 commit comments