@@ -227,6 +227,7 @@ pub struct RecursivePathSource<'gctx> {
227
227
loaded : bool ,
228
228
/// Packages that this sources has discovered.
229
229
packages : HashMap < PackageId , Vec < Package > > ,
230
+ warned_duplicate : HashSet < PackageId > ,
230
231
gctx : & ' gctx GlobalContext ,
231
232
}
232
233
@@ -245,6 +246,7 @@ impl<'gctx> RecursivePathSource<'gctx> {
245
246
path : root. to_path_buf ( ) ,
246
247
loaded : false ,
247
248
packages : Default :: default ( ) ,
249
+ warned_duplicate : Default :: default ( ) ,
248
250
gctx,
249
251
}
250
252
}
@@ -253,7 +255,13 @@ impl<'gctx> RecursivePathSource<'gctx> {
253
255
/// filesystem if package information haven't yet loaded.
254
256
pub fn read_packages ( & mut self ) -> CargoResult < Vec < Package > > {
255
257
self . load ( ) ?;
256
- Ok ( self . packages . iter ( ) . map ( |( _, v) | v[ 0 ] . clone ( ) ) . collect ( ) )
258
+ Ok ( self
259
+ . packages
260
+ . iter ( )
261
+ . map ( |( pkg_id, v) | {
262
+ first_package ( * pkg_id, v, & mut self . warned_duplicate , self . gctx ) . clone ( )
263
+ } )
264
+ . collect ( ) )
257
265
}
258
266
259
267
/// List all files relevant to building this package inside this source.
@@ -290,32 +298,6 @@ impl<'gctx> RecursivePathSource<'gctx> {
290
298
pub fn load ( & mut self ) -> CargoResult < ( ) > {
291
299
if !self . loaded {
292
300
self . packages = read_packages ( & self . path , self . source_id , self . gctx ) ?;
293
- for ( pkg_id, pkgs) in self . packages . iter ( ) {
294
- if 1 < pkgs. len ( ) {
295
- let ignored = pkgs[ 1 ..]
296
- . iter ( )
297
- // We can assume a package with publish = false isn't intended to be seen
298
- // by users so we can hide the warning about those since the user is unlikely
299
- // to care about those cases.
300
- . filter ( |pkg| pkg. publish ( ) . is_none ( ) )
301
- . collect :: < Vec < _ > > ( ) ;
302
- if !ignored. is_empty ( ) {
303
- use std:: fmt:: Write as _;
304
-
305
- let plural = if ignored. len ( ) == 1 { "" } else { "s" } ;
306
- let mut msg = String :: new ( ) ;
307
- let _ =
308
- writeln ! ( & mut msg, "skipping duplicate package{plural} `{pkg_id}`:" ) ;
309
- for ignored in ignored {
310
- let manifest_path = ignored. manifest_path ( ) . display ( ) ;
311
- let _ = writeln ! ( & mut msg, " {manifest_path}" ) ;
312
- }
313
- let manifest_path = pkgs[ 0 ] . manifest_path ( ) . display ( ) ;
314
- let _ = writeln ! ( & mut msg, "in favor of {manifest_path}" ) ;
315
- let _ = self . gctx . shell ( ) . warn ( msg) ;
316
- }
317
- }
318
- }
319
301
self . loaded = true ;
320
302
}
321
303
@@ -337,10 +319,13 @@ impl<'gctx> Source for RecursivePathSource<'gctx> {
337
319
f : & mut dyn FnMut ( IndexSummary ) ,
338
320
) -> Poll < CargoResult < ( ) > > {
339
321
self . load ( ) ?;
322
+ // TODO
340
323
for s in self
341
324
. packages
342
- . values ( )
343
- . map ( |pkgs| & pkgs[ 0 ] )
325
+ . iter ( )
326
+ . map ( |( pkg_id, pkgs) | {
327
+ first_package ( * pkg_id, pkgs, & mut self . warned_duplicate , self . gctx )
328
+ } )
344
329
. map ( |p| p. summary ( ) )
345
330
{
346
331
let matched = match kind {
@@ -371,7 +356,7 @@ impl<'gctx> Source for RecursivePathSource<'gctx> {
371
356
trace ! ( "getting packages; id={}" , id) ;
372
357
self . load ( ) ?;
373
358
let pkg = self . packages . get ( & id) ;
374
- pkg. map ( |pkgs| pkgs[ 0 ] . clone ( ) )
359
+ pkg. map ( |pkgs| first_package ( id , pkgs, & mut self . warned_duplicate , self . gctx ) . clone ( ) )
375
360
. map ( MaybePackage :: Ready )
376
361
. ok_or_else ( || internal ( format ! ( "failed to find {} in path source" , id) ) )
377
362
}
@@ -415,6 +400,38 @@ impl<'gctx> Source for RecursivePathSource<'gctx> {
415
400
}
416
401
}
417
402
403
+ fn first_package < ' p > (
404
+ pkg_id : PackageId ,
405
+ pkgs : & ' p Vec < Package > ,
406
+ warned_duplicate : & mut HashSet < PackageId > ,
407
+ gctx : & GlobalContext ,
408
+ ) -> & ' p Package {
409
+ if pkgs. len ( ) != 1 && warned_duplicate. insert ( pkg_id) {
410
+ let ignored = pkgs[ 1 ..]
411
+ . iter ( )
412
+ // We can assume a package with publish = false isn't intended to be seen
413
+ // by users so we can hide the warning about those since the user is unlikely
414
+ // to care about those cases.
415
+ . filter ( |pkg| pkg. publish ( ) . is_none ( ) )
416
+ . collect :: < Vec < _ > > ( ) ;
417
+ if !ignored. is_empty ( ) {
418
+ use std:: fmt:: Write as _;
419
+
420
+ let plural = if ignored. len ( ) == 1 { "" } else { "s" } ;
421
+ let mut msg = String :: new ( ) ;
422
+ let _ = writeln ! ( & mut msg, "skipping duplicate package{plural} `{pkg_id}`:" ) ;
423
+ for ignored in ignored {
424
+ let manifest_path = ignored. manifest_path ( ) . display ( ) ;
425
+ let _ = writeln ! ( & mut msg, " {manifest_path}" ) ;
426
+ }
427
+ let manifest_path = pkgs[ 0 ] . manifest_path ( ) . display ( ) ;
428
+ let _ = writeln ! ( & mut msg, "in favor of {manifest_path}" ) ;
429
+ let _ = gctx. shell ( ) . warn ( msg) ;
430
+ }
431
+ }
432
+ & pkgs[ 0 ]
433
+ }
434
+
418
435
/// List all files relevant to building this package inside this source.
419
436
///
420
437
/// This function will use the appropriate methods to determine the
0 commit comments