@@ -2,15 +2,15 @@ use std::{
2
2
collections:: HashMap ,
3
3
env,
4
4
fs:: { create_dir_all, File } ,
5
- io:: Write ,
6
- path:: Path ,
5
+ io:: { BufRead , Write } ,
6
+ path:: { Path , PathBuf } ,
7
7
process:: { Command , Stdio } ,
8
8
} ;
9
9
10
10
use bevy_api_gen:: * ;
11
11
use cargo_metadata:: camino:: Utf8Path ;
12
12
use clap:: Parser ;
13
- use log:: { debug, info} ;
13
+ use log:: { debug, error , info} ;
14
14
use strum:: VariantNames ;
15
15
use tera:: Context ;
16
16
@@ -25,19 +25,34 @@ fn main() {
25
25
}
26
26
env_logger:: init ( ) ;
27
27
28
+ info ! ( "Computing crate metadata" ) ;
28
29
let metadata = cargo_metadata:: MetadataCommand :: new ( )
29
30
. no_deps ( )
30
31
. other_options ( [ "--all-features" . to_string ( ) , "--offline" . to_string ( ) ] )
31
32
. exec ( )
32
33
. unwrap ( ) ;
34
+
33
35
let crates = metadata
34
36
. workspace_packages ( )
35
37
. iter ( )
36
38
. map ( |p| p. name . to_owned ( ) )
37
39
. collect :: < Vec < _ > > ( ) ;
40
+
41
+ info ! ( "Computing active features" ) ;
38
42
let include_crates = match ( & args. workspace_root , args. cmd . is_generate ( ) ) {
39
43
( Some ( root) , true ) => {
40
44
let feature_graph = FeatureGraph :: from_metadata ( & metadata, root) ;
45
+ info ! (
46
+ "Using workspace root: {}, found {} crates" ,
47
+ feature_graph. workspace_root,
48
+ feature_graph. crates. len( )
49
+ ) ;
50
+
51
+ info ! (
52
+ "Computing all transitive dependencies for enabled top-level features: {}" ,
53
+ args. features. join( "," )
54
+ ) ;
55
+
41
56
let dependencies = feature_graph
42
57
. dependencies_for_features ( args. features . as_ref ( ) , !args. no_default_features )
43
58
. into_iter ( )
@@ -52,6 +67,8 @@ fn main() {
52
67
let plugin_subdir = format ! ( "plugin-{}" , env!( "RUSTC_CHANNEL" ) ) ;
53
68
let plugin_target_dir = metadata. target_directory . join ( plugin_subdir) ;
54
69
70
+ info ! ( "Computing wokrspace metadata" ) ;
71
+
55
72
// inform the deps about the workspace crates, this is going to be useful when working with meta files as we will be able to
56
73
// know when to panic if a crate is not found
57
74
// it's also useful to pass around the output directory for our Args default values to be able to compute them
@@ -132,14 +149,13 @@ fn main() {
132
149
_ => { }
133
150
}
134
151
135
- let temp_dir = tempdir:: TempDir :: new ( "bevy_api_gen_bootstrap" )
136
- . expect ( "Error occured when trying to acquire temp file" ) ;
152
+ let temp_dir = find_bootstrap_dir ( ) ;
137
153
138
- debug ! ( "Temporary directory: {}" , & temp_dir. path ( ) . display( ) ) ;
154
+ debug ! ( "Bootstrap directory: {}" , & temp_dir. as_path ( ) . display( ) ) ;
139
155
140
- write_bootstrap_files ( temp_dir. path ( ) ) ;
156
+ write_bootstrap_files ( temp_dir. as_path ( ) ) ;
141
157
142
- let bootstrap_rlibs = build_bootstrap ( temp_dir. path ( ) , & plugin_target_dir. join ( "bootstrap" ) ) ;
158
+ let bootstrap_rlibs = build_bootstrap ( temp_dir. as_path ( ) , & plugin_target_dir. join ( "bootstrap" ) ) ;
143
159
144
160
if bootstrap_rlibs. len ( ) == BOOTSTRAP_DEPS . len ( ) {
145
161
let extern_args = bootstrap_rlibs
@@ -195,20 +211,50 @@ fn build_bootstrap(
195
211
let mut cmd = Command :: new ( "cargo" )
196
212
. current_dir ( temp_dir)
197
213
. stdout ( Stdio :: piped ( ) )
214
+ . stderr ( Stdio :: piped ( ) )
198
215
. args ( [ "build" , "--message-format=json" ] )
199
216
. spawn ( )
200
217
. unwrap ( ) ;
201
218
219
+ info ! (
220
+ "cd {} && cargo build --message-format=json" ,
221
+ temp_dir. display( )
222
+ ) ;
223
+
202
224
let reader = std:: io:: BufReader :: new ( cmd. stdout . take ( ) . unwrap ( ) ) ;
225
+ let err_reader = std:: io:: BufReader :: new ( cmd. stderr . take ( ) . unwrap ( ) ) ;
203
226
204
227
std:: fs:: create_dir_all ( cache_dir) . unwrap ( ) ;
205
228
206
229
let mut bootstrap_rlibs = HashMap :: with_capacity ( BOOTSTRAP_DEPS . len ( ) ) ;
207
230
for msg in cargo_metadata:: Message :: parse_stream ( reader) {
208
- if let cargo_metadata:: Message :: CompilerArtifact ( artifact) = msg. unwrap ( ) {
231
+ let msg = msg. unwrap ( ) ;
232
+ if let cargo_metadata:: Message :: CompilerArtifact ( artifact) = msg {
209
233
for artifact in artifact. filenames . into_iter ( ) {
210
234
process_artifact ( artifact, & mut bootstrap_rlibs) ;
211
235
}
236
+ } else {
237
+ match msg {
238
+ cargo_metadata:: Message :: BuildFinished ( finished) => {
239
+ if !finished. success {
240
+ error ! ( "Bootstrapping crate failed to build artifact" ) ;
241
+ }
242
+ }
243
+ cargo_metadata:: Message :: TextLine ( t) => {
244
+ info ! ( "{t}" ) ;
245
+ }
246
+ cargo_metadata:: Message :: CompilerMessage ( msg) => {
247
+ info ! ( "{msg}" ) ;
248
+ }
249
+ _ => { }
250
+ }
251
+ }
252
+ }
253
+ for msg in err_reader. lines ( ) {
254
+ if let Ok ( line) = msg {
255
+ info ! ( "{line}" ) ;
256
+ } else {
257
+ panic ! ( "Failed to read cargo stderr" ) ;
212
258
}
213
259
}
214
260
@@ -224,10 +270,17 @@ fn build_bootstrap(
224
270
std:: fs:: copy ( path, dest) . unwrap ( ) ;
225
271
}
226
272
}
273
+ match cmd. wait ( ) {
274
+ Ok ( status) => {
275
+ if !status. success ( ) {
276
+ panic ! ( "Building bootstrap crate returned a failure status code" ) ;
277
+ }
278
+ }
279
+ Err ( e) => {
280
+ panic ! ( "Failed to wait on cargo build process: {}" , e) ;
281
+ }
282
+ }
227
283
228
- if !cmd. wait ( ) . unwrap ( ) . success ( ) {
229
- panic ! ( "Building bootstrap crate returned a failure status code" ) ;
230
- } ;
231
284
bootstrap_rlibs
232
285
}
233
286
@@ -248,6 +301,26 @@ fn process_artifact(
248
301
}
249
302
}
250
303
304
+ /// finds best location for bootstrapping crate
305
+ /// this will be the nearest target/bevy_api_gen_bootstrap directory
306
+ fn find_bootstrap_dir ( ) -> PathBuf {
307
+ let mut path = env:: current_dir ( ) . unwrap ( ) ;
308
+ loop {
309
+ if path. join ( "target" ) . exists ( ) {
310
+ break ;
311
+ } else {
312
+ path = path. parent ( ) . unwrap ( ) . to_owned ( ) ;
313
+ }
314
+ }
315
+
316
+ path. push ( "target" ) ;
317
+ path. push ( "bevy_api_gen_bootstrap" ) ;
318
+
319
+ // create all the directories
320
+ create_dir_all ( & path) . unwrap ( ) ;
321
+ path
322
+ }
323
+
251
324
/// Generate bootstrapping crate files
252
325
fn write_bootstrap_files ( path : & Path ) {
253
326
// write manifest file 'Cargo.toml'
0 commit comments