@@ -7,38 +7,35 @@ use crate::cache::INTERNER;
7
7
use crate :: util:: output;
8
8
use crate :: { Build , Crate } ;
9
9
10
- #[ derive( Deserialize ) ]
10
+ /// For more information, see the output of
11
+ /// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
12
+ #[ derive( Debug , Deserialize ) ]
11
13
struct Output {
12
14
packages : Vec < Package > ,
13
15
}
14
16
15
- #[ derive( Deserialize ) ]
17
+ /// For more information, see the output of
18
+ /// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
19
+ #[ derive( Debug , Deserialize ) ]
16
20
struct Package {
17
21
name : String ,
18
22
source : Option < String > ,
19
23
manifest_path : String ,
20
24
dependencies : Vec < Dependency > ,
21
25
}
22
26
23
- #[ derive( Deserialize ) ]
27
+ /// For more information, see the output of
28
+ /// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html>
29
+ #[ derive( Debug , Deserialize ) ]
24
30
struct Dependency {
25
31
name : String ,
26
32
source : Option < String > ,
27
33
}
28
34
35
+ /// Collects and stores package metadata of each workspace members into `build`,
36
+ /// by executing `cargo metadata` commands.
29
37
pub fn build ( build : & mut Build ) {
30
- // Run `cargo metadata` to figure out what crates we're testing.
31
- let mut cargo = Command :: new ( & build. initial_cargo ) ;
32
- cargo
33
- . arg ( "metadata" )
34
- . arg ( "--format-version" )
35
- . arg ( "1" )
36
- . arg ( "--no-deps" )
37
- . arg ( "--manifest-path" )
38
- . arg ( build. src . join ( "Cargo.toml" ) ) ;
39
- let output = output ( & mut cargo) ;
40
- let output: Output = serde_json:: from_str ( & output) . unwrap ( ) ;
41
- for package in output. packages {
38
+ for package in workspace_members ( build) {
42
39
if package. source . is_none ( ) {
43
40
let name = INTERNER . intern_string ( package. name ) ;
44
41
let mut path = PathBuf :: from ( package. manifest_path ) ;
@@ -57,3 +54,35 @@ pub fn build(build: &mut Build) {
57
54
}
58
55
}
59
56
}
57
+
58
+ /// Invokes `cargo metadata` to get package metadata of each workspace member.
59
+ ///
60
+ /// Note that `src/tools/cargo` is no longer a workspace member but we still
61
+ /// treat it as one here, by invoking an additional `cargo metadata` command.
62
+ fn workspace_members ( build : & Build ) -> impl Iterator < Item = Package > {
63
+ let cmd_metadata = |manifest_path| {
64
+ let mut cargo = Command :: new ( & build. initial_cargo ) ;
65
+ cargo
66
+ . arg ( "metadata" )
67
+ . arg ( "--format-version" )
68
+ . arg ( "1" )
69
+ . arg ( "--no-deps" )
70
+ . arg ( "--manifest-path" )
71
+ . arg ( manifest_path) ;
72
+ cargo
73
+ } ;
74
+
75
+ // Collects `metadata.packages` from the root workspace.
76
+ let root_manifest_path = build. src . join ( "Cargo.toml" ) ;
77
+ let root_output = output ( & mut cmd_metadata ( & root_manifest_path) ) ;
78
+ let Output { packages, .. } = serde_json:: from_str ( & root_output) . unwrap ( ) ;
79
+
80
+ // Collects `metadata.packages` from src/tools/cargo separately.
81
+ let cargo_manifest_path = build. src . join ( "src/tools/cargo/Cargo.toml" ) ;
82
+ let cargo_output = output ( & mut cmd_metadata ( & cargo_manifest_path) ) ;
83
+ let Output { packages : cargo_packages, .. } = serde_json:: from_str ( & cargo_output) . unwrap ( ) ;
84
+
85
+ // We only care about the root package from `src/tool/cargo` workspace.
86
+ let cargo_package = cargo_packages. into_iter ( ) . find ( |pkg| pkg. name == "cargo" ) . into_iter ( ) ;
87
+ packages. into_iter ( ) . chain ( cargo_package)
88
+ }
0 commit comments