16
16
17
17
use super :: { Crate , CrateType , Extern , ExternType } ;
18
18
use crate :: config:: VariantConfig ;
19
- use anyhow:: { anyhow , bail, Context , Result } ;
19
+ use anyhow:: { bail, Context , Result } ;
20
20
use serde:: Deserialize ;
21
21
use std:: collections:: BTreeMap ;
22
22
use std:: ops:: Deref ;
@@ -268,14 +268,22 @@ fn make_extern(packages: &[PackageMetadata], dependency: &DependencyMetadata) ->
268
268
Ok ( Extern { name, lib_name, extern_type } )
269
269
}
270
270
271
- /// Given a package ID like
272
- /// `"either 1.8.1 (path+file:///usr/local/google/home/qwandor/aosp/external/rust/crates/either)"`,
273
- /// returns the path to the package, e.g.
274
- /// `"/usr/local/google/home/qwandor/aosp/external/rust/crates/either"`.
271
+ /// Given a Cargo package ID, returns the path.
272
+ ///
273
+ /// Extracts `"/path/to/crate"` from
274
+ /// `"path+file:///path/to/crate#1.2.3"`. See
275
+ /// https://doc.rust-lang.org/cargo/reference/pkgid-spec.html for
276
+ /// information on Cargo package ID specifications.
275
277
fn package_dir_from_id ( id : & str ) -> Result < PathBuf > {
276
- const URI_MARKER : & str = "(path+file://" ;
277
- let uri_start = id. find ( URI_MARKER ) . ok_or_else ( || anyhow ! ( "Invalid package ID {}" , id) ) ?;
278
- Ok ( PathBuf :: from ( id[ uri_start + URI_MARKER . len ( ) ..id. len ( ) - 1 ] . to_string ( ) ) )
278
+ const PREFIX : & str = "path+file://" ;
279
+ const SEPARATOR : char = '#' ;
280
+ let Some ( stripped) = id. strip_prefix ( PREFIX ) else {
281
+ bail ! ( "Invalid package ID {id:?}, expected it to start with {PREFIX:?}" ) ;
282
+ } ;
283
+ let Some ( idx) = stripped. rfind ( SEPARATOR ) else {
284
+ bail ! ( "Invalid package ID {id:?}, expected it to contain {SEPARATOR:?}" ) ;
285
+ } ;
286
+ Ok ( PathBuf :: from ( stripped[ ..idx] . to_string ( ) ) )
279
287
}
280
288
281
289
fn split_src_path < ' a > ( src_path : & ' a Path , package_dir : & Path ) -> & ' a Path {
@@ -344,8 +352,19 @@ mod tests {
344
352
use super :: * ;
345
353
use crate :: config:: Config ;
346
354
use crate :: tests:: testdata_directories;
355
+ use googletest:: matchers:: eq;
356
+ use googletest:: prelude:: assert_that;
347
357
use std:: fs:: { read_to_string, File } ;
348
358
359
+ #[ test]
360
+ fn extract_package_dir_from_id ( ) -> Result < ( ) > {
361
+ assert_eq ! (
362
+ package_dir_from_id( "path+file:///path/to/crate#1.2.3" ) ?,
363
+ PathBuf :: from( "/path/to/crate" )
364
+ ) ;
365
+ Ok ( ( ) )
366
+ }
367
+
349
368
#[ test]
350
369
fn resolve_multi_level_feature_dependencies ( ) {
351
370
let chosen = vec ! [ "default" . to_string( ) , "extra" . to_string( ) , "on_by_default" . to_string( ) ] ;
@@ -419,6 +438,20 @@ mod tests {
419
438
420
439
#[ test]
421
440
fn parse_metadata ( ) {
441
+ /// Remove anything before "external/rust/crates/" from the
442
+ /// `package_dir` field. This makes the test robust since you
443
+ /// can use `cargo metadata` to regenerate the test files and
444
+ /// you don't have to care about where your AOSP checkout
445
+ /// lives.
446
+ fn normalize_package_dir ( mut c : Crate ) -> Crate {
447
+ const EXTERNAL_RUST_CRATES : & str = "external/rust/crates/" ;
448
+ let package_dir = c. package_dir . to_str ( ) . unwrap ( ) ;
449
+ if let Some ( idx) = package_dir. find ( EXTERNAL_RUST_CRATES ) {
450
+ c. package_dir = PathBuf :: from ( format ! ( ".../{}" , & package_dir[ idx..] ) ) ;
451
+ }
452
+ c
453
+ }
454
+
422
455
for testdata_directory_path in testdata_directories ( ) {
423
456
let cfg = Config :: from_json_str (
424
457
& read_to_string ( testdata_directory_path. join ( "cargo_embargo.json" ) )
@@ -432,10 +465,13 @@ mod tests {
432
465
)
433
466
. unwrap ( ) ;
434
467
let cargo_metadata_path = testdata_directory_path. join ( "cargo.metadata" ) ;
435
- let expected_crates: Vec < Vec < Crate > > = serde_json:: from_reader (
468
+ let expected_crates: Vec < Vec < Crate > > = serde_json:: from_reader :: < _ , Vec < Vec < Crate > > > (
436
469
File :: open ( testdata_directory_path. join ( "crates.json" ) ) . unwrap ( ) ,
437
470
)
438
- . unwrap ( ) ;
471
+ . unwrap ( )
472
+ . into_iter ( )
473
+ . map ( |crates : Vec < Crate > | crates. into_iter ( ) . map ( normalize_package_dir) . collect ( ) )
474
+ . collect ( ) ;
439
475
440
476
let crates = cfg
441
477
. variants
@@ -448,9 +484,12 @@ mod tests {
448
484
variant_cfg,
449
485
)
450
486
. unwrap ( )
487
+ . into_iter ( )
488
+ . map ( normalize_package_dir)
489
+ . collect :: < Vec < Crate > > ( )
451
490
} )
452
- . collect :: < Vec < _ > > ( ) ;
453
- assert_eq ! ( crates, expected_crates) ;
491
+ . collect :: < Vec < Vec < Crate > > > ( ) ;
492
+ assert_that ! ( format! ( "{ crates:#?}" ) , eq ( format! ( "{ expected_crates:#?}" ) ) ) ;
454
493
}
455
494
}
456
495
}
0 commit comments