@@ -178,7 +178,12 @@ enum Xtasks {
178
178
/// Build the main workspace, apply all prefferred lints
179
179
Check ,
180
180
/// Build the rust crates.io docs as well as any other docs
181
- Docs ,
181
+ Docs {
182
+ /// Open in browser
183
+ /// This will open the generated docs in the default browser
184
+ #[ clap( long, short) ]
185
+ open : bool ,
186
+ } ,
182
187
/// Build the main workspace, and then run all tests
183
188
Test ,
184
189
/// Perform a full check as it would be done in CI
@@ -190,7 +195,7 @@ impl Xtasks {
190
195
match self {
191
196
Xtasks :: Build => Self :: build ( features) ,
192
197
Xtasks :: Check => Self :: check ( features) ,
193
- Xtasks :: Docs => Self :: docs ( ) ,
198
+ Xtasks :: Docs { open } => Self :: docs ( open ) ,
194
199
Xtasks :: Test => Self :: test ( features) ,
195
200
Xtasks :: CiCheck => Self :: cicd ( ) ,
196
201
Xtasks :: Init => Self :: init ( ) ,
@@ -212,22 +217,35 @@ impl Xtasks {
212
217
Ok ( workspace_root. into ( ) )
213
218
}
214
219
220
+ fn relative_workspace_dir < P : AsRef < Path > > ( dir : P ) -> Result < std:: path:: PathBuf > {
221
+ let workspace_dir = Self :: workspace_dir ( ) ?;
222
+ Ok ( workspace_dir. join ( dir) )
223
+ }
224
+
215
225
fn run_system_command < I : IntoIterator < Item = impl AsRef < OsStr > > > (
216
226
command : & str ,
217
227
context : & str ,
218
228
add_args : I ,
229
+ dir : Option < & Path > ,
219
230
) -> Result < ( ) > {
220
231
info ! ( "Running system command: {}" , command) ;
221
232
233
+ let working_dir = match dir {
234
+ Some ( d) => Self :: relative_workspace_dir ( d) ?,
235
+ None => Self :: workspace_dir ( ) ?,
236
+ } ;
237
+
222
238
let mut cmd = Command :: new ( command) ;
223
239
cmd. args ( add_args)
224
240
. stdout ( std:: process:: Stdio :: inherit ( ) )
225
241
. stderr ( std:: process:: Stdio :: inherit ( ) )
226
- . current_dir ( Self :: workspace_dir ( ) ? ) ;
242
+ . current_dir ( working_dir ) ;
227
243
228
244
info ! ( "Using command: {:?}" , cmd) ;
229
245
230
- let output = cmd. output ( ) . with_context ( || context. to_owned ( ) ) ?;
246
+ let output = cmd. output ( ) ;
247
+ info ! ( "Command output: {:?}" , output) ;
248
+ let output = output. with_context ( || context. to_owned ( ) ) ?;
231
249
match output. status . code ( ) {
232
250
Some ( 0 ) => Ok ( ( ) ) ,
233
251
_ => bail ! (
@@ -257,17 +275,17 @@ impl Xtasks {
257
275
. expect ( "invalid command argument" )
258
276
. to_owned ( )
259
277
} ) ) ;
260
- let workspace_dir = Self :: workspace_dir ( ) ? ;
261
- let workspace_dir = match dir {
262
- Some ( d) => workspace_dir . join ( d) ,
263
- None => workspace_dir,
278
+
279
+ let working_dir = match dir {
280
+ Some ( d) => Self :: relative_workspace_dir ( d) ? ,
281
+ None => Self :: workspace_dir ( ) ? ,
264
282
} ;
265
283
266
284
let mut cmd = Command :: new ( "cargo" ) ;
267
285
cmd. args ( args)
268
286
. stdout ( std:: process:: Stdio :: inherit ( ) )
269
287
. stderr ( std:: process:: Stdio :: inherit ( ) )
270
- . current_dir ( workspace_dir ) ;
288
+ . current_dir ( working_dir ) ;
271
289
272
290
info ! ( "Using command: {:?}" , cmd) ;
273
291
@@ -309,21 +327,37 @@ impl Xtasks {
309
327
"cargo" ,
310
328
"Failed to run cargo fmt" ,
311
329
vec ! [ "fmt" , "--all" , "--" , "--check" ] ,
330
+ None ,
312
331
) ?;
313
332
314
333
Ok ( ( ) )
315
334
}
316
335
317
- fn docs ( ) -> Result < ( ) > {
336
+ fn docs ( open : bool ) -> Result < ( ) > {
318
337
// find [package.metadata."docs.rs"] key in Cargo.toml
319
338
let metadata = Self :: cargo_metadata ( ) ?;
320
- let package = metadata. root_package ( ) . expect ( "no root package" ) ;
339
+
340
+ let package = metadata
341
+ . packages
342
+ . iter ( )
343
+ . find ( |p| p. name == "bevy_mod_scripting" )
344
+ . expect ( "Could not find bevy_mod_scripting package in metadata" ) ;
345
+
346
+ info ! ( "Building with root package: {}" , package. name) ;
347
+
321
348
let docs_rs = package
322
349
. metadata
323
350
. get ( "docs.rs" )
324
351
. expect ( "no docs.rs metadata" ) ;
325
352
326
- let string_list = docs_rs
353
+ let features = docs_rs
354
+ . as_object ( )
355
+ . expect ( "docs.rs metadata is not an object" )
356
+ . get ( "features" )
357
+ . expect ( "no 'features' in docs.rs metadata" ) ;
358
+
359
+ info ! ( "Using docs.rs metadata: {:?}" , docs_rs) ;
360
+ let string_list = features
327
361
. as_array ( )
328
362
. expect ( "docs.rs metadata is not an array" )
329
363
. iter ( )
@@ -333,22 +367,29 @@ impl Xtasks {
333
367
334
368
let features = Features ( string_list) ;
335
369
370
+ let mut args = Vec :: default ( ) ;
371
+ args. push ( "--all" ) ;
372
+ if open {
373
+ args. push ( "--open" ) ;
374
+ }
336
375
Self :: run_workspace_command (
337
376
"doc" ,
338
377
"Failed to build crates.io docs" ,
339
378
features. clone ( ) ,
340
- vec ! [ "--all" ] ,
379
+ args ,
341
380
None ,
342
381
) ?;
343
382
344
383
// build mdbook
345
- Self :: run_workspace_command (
384
+ let args = if open { vec ! [ "build" ] } else { vec ! [ "serve" ] } ;
385
+
386
+ Self :: run_system_command (
346
387
"mdbook" ,
347
- "Failed to build mdbook docs" ,
348
- features,
349
- vec ! [ "--all" ] ,
388
+ "Failed to build or serve mdbook docs" ,
389
+ args,
350
390
Some ( Path :: new ( "docs" ) ) ,
351
391
) ?;
392
+
352
393
Ok ( ( ) )
353
394
}
354
395
@@ -395,6 +436,7 @@ impl Xtasks {
395
436
"-o" ,
396
437
"target/coverage/html" ,
397
438
] ,
439
+ None ,
398
440
) ?;
399
441
400
442
Self :: run_system_command (
@@ -417,6 +459,7 @@ impl Xtasks {
417
459
"-o" ,
418
460
"target/coverage/lcov.info" ,
419
461
] ,
462
+ None ,
420
463
)
421
464
}
422
465
@@ -454,6 +497,9 @@ impl Xtasks {
454
497
let all_features = Features :: all_features ( ) ;
455
498
Self :: check ( all_features. clone ( ) ) ?;
456
499
500
+ // run docs
501
+ Self :: docs ( false ) ?;
502
+
457
503
// run tests
458
504
Self :: test ( all_features) ?;
459
505
0 commit comments