11use std:: {
2+ collections:: BTreeMap ,
23 env, fs,
34 io:: { self as std_io, Read } ,
45 path:: Path ,
@@ -9,6 +10,7 @@ use anyhow::{ensure, Context, Result};
910use cargo_lock:: { package:: SourceKind , Checksum , Lockfile } ;
1011use cargo_toml:: Manifest ;
1112use git:: GitUrl ;
13+ use rayon:: iter:: { IntoParallelIterator , ParallelIterator } ;
1214use serde:: Deserialize ;
1315use sha2:: { Digest as _, Sha256 } ;
1416use url:: Url ;
@@ -76,45 +78,62 @@ fn main() -> Result<()> {
7678
7779 let lock = Lockfile :: load ( lock) . context ( "decode Cargo.lock" ) ?;
7880
79- for lock_info in lock. packages {
80- let name = lock_info. name . clone ( ) ;
81- let version = lock_info. version . clone ( ) ;
81+ let resolved_packages = lock
82+ . packages
83+ . into_par_iter ( )
84+ . filter_map ( |lock_info| {
85+ let name = lock_info. name . clone ( ) ;
86+ let version = lock_info. version . clone ( ) ;
8287
83- let resolved_package = match resolve_package ( & http_client, & crates_dir, lock_info) {
84- Ok ( resolved_package) => resolved_package,
85- Err ( err) => {
86- println ! ( "Couldn't resolve package {name} v{version} err={err:?}" ) ;
87- continue ;
88+ match resolve_package ( & http_client, & crates_dir, lock_info) {
89+ Ok ( resolved_package) => Some ( resolved_package) ,
90+ Err ( err) => {
91+ println ! ( "Couldn't resolve package {name} v{version} err={err:?}" ) ;
92+ None
93+ }
8894 }
89- } ;
95+ } )
96+ . collect :: < Vec < _ > > ( ) ;
97+
98+ let mut grouped_resolved_packages = BTreeMap :: < _ , Vec < _ > > :: new ( ) ;
99+ for resolved_package in resolved_packages {
100+ grouped_resolved_packages
101+ . entry ( resolved_package. repository_url . clone ( ) )
102+ . or_default ( )
103+ . push ( resolved_package) ;
104+ }
90105
91- let mut git_repository =
92- match GitRepository :: obtain ( & repos_dir, resolved_package. repository_url . clone ( ) ) {
106+ grouped_resolved_packages
107+ . into_par_iter ( )
108+ . for_each ( |( repository_url, resolved_packages) | {
109+ let mut git_repository = match GitRepository :: obtain ( & repos_dir, repository_url) {
93110 Ok ( git_repository) => git_repository,
94111 Err ( err) => {
95112 println ! (
96113 "Couldn't obtain git repository for {} v{} err={:?} url={}" ,
114+ resolved_packages[ 0 ] . lock_info. name,
115+ resolved_packages[ 0 ] . lock_info. version,
116+ err,
117+ resolved_packages[ 0 ] . repository_url
118+ ) ;
119+ return ;
120+ }
121+ } ;
122+
123+ for resolved_package in resolved_packages {
124+ if let Err ( err) =
125+ analyze_package ( & default_toolchain, & resolved_package, & mut git_repository)
126+ {
127+ println ! (
128+ "Couldn't analyze package for {} v{} err={:?} url={}" ,
97129 resolved_package. lock_info. name,
98130 resolved_package. lock_info. version,
99131 err,
100132 resolved_package. repository_url
101133 ) ;
102- continue ;
103134 }
104- } ;
105-
106- if let Err ( err) =
107- analyze_package ( & default_toolchain, & resolved_package, & mut git_repository)
108- {
109- println ! (
110- "Couldn't analyze package for {} v{} err={:?} url={}" ,
111- resolved_package. lock_info. name,
112- resolved_package. lock_info. version,
113- err,
114- resolved_package. repository_url
115- ) ;
116- }
117- }
135+ }
136+ } ) ;
118137
119138 Ok ( ( ) )
120139}
0 commit comments