@@ -23,6 +23,7 @@ use std::{
23
23
} ;
24
24
25
25
use anyhow:: { anyhow, Context , Result } ;
26
+ use crates_index:: DependencyKind ;
26
27
use glob:: glob;
27
28
use google_metadata:: GoogleMetadata ;
28
29
use itertools:: Itertools ;
@@ -364,6 +365,75 @@ impl ManagedRepo {
364
365
365
366
Ok ( ( ) )
366
367
}
368
+ pub fn analyze_import ( & self , crate_name : & str ) -> Result < ( ) > {
369
+ if self . contains ( crate_name) {
370
+ println ! ( "Crate already imported at {}" , self . managed_dir_for( crate_name) ) ;
371
+ return Ok ( ( ) ) ;
372
+ }
373
+ let legacy_dir = self . legacy_dir_for ( crate_name, None ) ?;
374
+ if legacy_dir. abs ( ) . exists ( ) {
375
+ println ! ( "Legacy crate already imported at {}" , legacy_dir) ;
376
+ return Ok ( ( ) ) ;
377
+ }
378
+
379
+ let mut managed_crates = self . new_cc ( ) ;
380
+ managed_crates. add_from ( self . managed_dir ( ) . rel ( ) ) ?;
381
+ let legacy_crates = self . legacy_crates ( ) ?;
382
+
383
+ let cio_crate = self . crates_io . get_crate ( crate_name) ?;
384
+
385
+ for version in cio_crate. versions ( ) {
386
+ println ! ( "Version {}" , version. version( ) ) ;
387
+ let mut found_problems = false ;
388
+ for ( dep, req) in version. android_deps_with_version_reqs ( ) {
389
+ let cc = if managed_crates. contains_name ( dep. crate_name ( ) ) {
390
+ & managed_crates
391
+ } else {
392
+ & legacy_crates
393
+ } ;
394
+ if !cc. contains_name ( dep. crate_name ( ) ) {
395
+ found_problems = true ;
396
+ println ! (
397
+ " Dep {} {} has not been imported to Android" ,
398
+ dep. crate_name( ) ,
399
+ dep. requirement( )
400
+ ) ;
401
+ if matches ! ( dep. kind( ) , DependencyKind :: Dev ) {
402
+ println ! ( " But this is a dev dependency, probably only needed if you want to run the tests" ) ;
403
+ }
404
+ if dep. is_optional ( ) {
405
+ println ! ( " But this is an optional dependency, used by the following features: {}" , dep. features( ) . join( ", " ) ) ;
406
+ }
407
+ continue ;
408
+ }
409
+ let versions = cc. get_versions ( dep. crate_name ( ) ) . collect :: < Vec < _ > > ( ) ;
410
+ let has_matching_version =
411
+ versions. iter ( ) . any ( |( nv, _) | req. matches_relaxed ( nv. version ( ) ) ) ;
412
+ if !has_matching_version {
413
+ found_problems = true ;
414
+ }
415
+ if !has_matching_version || versions. len ( ) > 1 {
416
+ if has_matching_version {
417
+ println ! ( " Dep {} has multiple versions available. You may need to override the default choice in cargo_embargo.json" , dep. crate_name( ) ) ;
418
+ }
419
+ for ( _, dep_crate) in versions {
420
+ println ! (
421
+ " Dep {} {} is {}satisfied by v{} at {}" ,
422
+ dep. crate_name( ) ,
423
+ dep. requirement( ) ,
424
+ if req. matches_relaxed( dep_crate. version( ) ) { "" } else { "not " } ,
425
+ dep_crate. version( ) ,
426
+ dep_crate. path( )
427
+ ) ;
428
+ }
429
+ }
430
+ }
431
+ if !found_problems {
432
+ println ! ( " No problems found with this version." )
433
+ }
434
+ }
435
+ Ok ( ( ) )
436
+ }
367
437
pub fn import ( & self , crate_name : & str ) -> Result < ( ) > {
368
438
let ( new_deps, pseudo_crate) = self . add_crate_and_dependencies ( crate_name) ?;
369
439
0 commit comments