@@ -14,6 +14,7 @@ use anyhow::Context as _;
14
14
use cargo_util:: paths;
15
15
use filetime:: FileTime ;
16
16
use gix:: bstr:: ByteVec ;
17
+ use gix:: dir:: entry:: Status ;
17
18
use ignore:: gitignore:: GitignoreBuilder ;
18
19
use tracing:: { trace, warn} ;
19
20
use walkdir:: WalkDir ;
@@ -475,7 +476,6 @@ impl<'gctx> PathSource<'gctx> {
475
476
repo : & gix:: Repository ,
476
477
filter : & dyn Fn ( & Path , bool ) -> bool ,
477
478
) -> CargoResult < Vec < PathBuf > > {
478
- use gix:: dir:: entry:: Status ;
479
479
warn ! ( "list_files_gix {}" , pkg. package_id( ) ) ;
480
480
let options = repo
481
481
. dirwalk_options ( ) ?
@@ -521,129 +521,45 @@ impl<'gctx> PathSource<'gctx> {
521
521
} ;
522
522
include. to_mut ( ) . insert_str ( 0 , ":/" ) ;
523
523
524
- vec ! [ include, exclude]
524
+ vec ! [ include. into_owned ( ) , exclude. into_owned ( ) ]
525
525
} ;
526
526
527
- let mut delegate = Delegate :: new ( self , pkg, pkg_path, root, filter) ?;
528
- repo. dirwalk (
529
- & index,
530
- pathspec,
531
- & Default :: default ( ) ,
532
- options,
533
- & mut delegate,
534
- ) ?;
535
-
536
- let ( mut files, mut subpackages_found) = delegate. into_result ( ) ?;
537
- // Append all normal files that might be tracked in `target/`.
538
- for entry in index
539
- . prefixed_entries ( target_prefix. as_ref ( ) )
540
- . unwrap_or_default ( )
541
- . iter ( )
542
- // probably not needed as conflicts prevent this to run, but let's be explicit.
543
- . filter ( |entry| entry. stage ( ) == 0 )
544
- {
545
- handle_path (
546
- entry. path ( & index) ,
547
- // Do not trust what's recorded in the index, enforce checking the disk.
548
- // This traversal is not part of a `status()`, and tracking things in `target/`
549
- // is rare.
550
- None ,
551
- root,
552
- pkg,
553
- pkg_path,
554
- self ,
555
- & mut files,
556
- & mut subpackages_found,
557
- filter,
558
- ) ?
559
- }
560
- return Ok ( files) ;
561
-
562
- struct Delegate < ' a , ' gctx > {
563
- root : & ' a Path ,
564
- pkg : & ' a Package ,
565
- pkg_path : & ' a Path ,
566
- parent : & ' a PathSource < ' gctx > ,
567
- paths : Vec < PathBuf > ,
568
- subpackages_found : Vec < PathBuf > ,
569
- filter : & ' a dyn Fn ( & Path , bool ) -> bool ,
570
- err : Option < anyhow:: Error > ,
571
- }
572
-
573
- impl < ' a , ' gctx > gix:: dir:: walk:: Delegate for Delegate < ' a , ' gctx > {
574
- fn emit (
575
- & mut self ,
576
- entry : gix:: dir:: EntryRef < ' _ > ,
577
- _collapsed_directory_status : Option < Status > ,
578
- ) -> gix:: dir:: walk:: Action {
579
- match self . handle_entry ( entry) {
580
- Ok ( ( ) ) => gix:: dir:: walk:: Action :: Continue ,
581
- Err ( e) => {
582
- self . err = Some ( e. into ( ) ) ;
583
- gix:: dir:: walk:: Action :: Cancel
584
- }
585
- }
586
- }
587
- }
588
-
589
- impl < ' a , ' gctx > Delegate < ' a , ' gctx > {
590
- fn new (
591
- parent : & ' a PathSource < ' gctx > ,
592
- pkg : & ' a Package ,
593
- pkg_path : & ' a Path ,
594
- root : & ' a Path ,
595
- filter : & ' a dyn Fn ( & Path , bool ) -> bool ,
596
- ) -> CargoResult < Self > {
597
- Ok ( Self {
598
- root,
599
- pkg,
600
- pkg_path,
601
- parent,
602
- filter,
603
- paths : vec ! [ ] ,
604
- subpackages_found : vec ! [ ] ,
605
- err : None ,
527
+ let mut files = Vec :: < PathBuf > :: new ( ) ;
528
+ let mut subpackages_found = Vec :: new ( ) ;
529
+ for item in repo
530
+ . dirwalk_iter ( index. clone ( ) , pathspec, Default :: default ( ) , options) ?
531
+ . filter ( |res| {
532
+ // Don't include Cargo.lock if it is untracked. Packaging will
533
+ // generate a new one as needed.
534
+ res. as_ref ( ) . map_or ( true , |item| {
535
+ !( item. entry . status == Status :: Untracked
536
+ && item. entry . rela_path == "Cargo.lock" )
606
537
} )
607
- }
608
-
609
- fn into_result ( self ) -> CargoResult < ( Vec < PathBuf > , Vec < PathBuf > ) > {
610
- match self . err {
611
- None => {
612
- return Ok ( ( self . paths , self . subpackages_found ) ) ;
613
- }
614
- Some ( e) => return Err ( e) ,
615
- }
616
- }
617
-
618
- fn handle_entry ( & mut self , entry : gix:: dir:: EntryRef < ' _ > ) -> CargoResult < ( ) > {
619
- if entry. status == Status :: Untracked && entry. rela_path . as_ref ( ) == "Cargo.lock" {
620
- return Ok ( ( ) ) ;
621
- }
622
- handle_path (
623
- entry. rela_path . as_ref ( ) ,
624
- entry. disk_kind ,
625
- self . root ,
626
- self . pkg ,
627
- self . pkg_path ,
628
- self . parent ,
629
- & mut self . paths ,
630
- & mut self . subpackages_found ,
631
- self . filter ,
632
- )
633
- }
634
- }
635
-
636
- fn handle_path (
637
- rela_path : & gix:: bstr:: BStr ,
638
- kind : Option < gix:: dir:: entry:: Kind > ,
639
- root : & Path ,
640
- pkg : & Package ,
641
- pkg_path : & Path ,
642
- source : & PathSource < ' _ > ,
643
- paths : & mut Vec < PathBuf > ,
644
- subpackages_found : & mut Vec < PathBuf > ,
645
- filter : & dyn Fn ( & Path , bool ) -> bool ,
646
- ) -> CargoResult < ( ) > {
538
+ } )
539
+ . map ( |res| res. map ( |item| ( item. entry . rela_path , item. entry . disk_kind ) ) )
540
+ . chain (
541
+ // Append entries that might be tracked in `<pkg_root>/target/`.
542
+ index
543
+ . prefixed_entries ( target_prefix. as_ref ( ) )
544
+ . unwrap_or_default ( )
545
+ . iter ( )
546
+ . filter ( |entry| {
547
+ // probably not needed as conflicts prevent this to run, but let's be explicit.
548
+ entry. stage ( ) == 0
549
+ } )
550
+ . map ( |entry| {
551
+ (
552
+ entry. path ( & index) . to_owned ( ) ,
553
+ // Do not trust what's recorded in the index, enforce checking the disk.
554
+ // This traversal is not part of a `status()`, and tracking things in `target/`
555
+ // is rare.
556
+ None ,
557
+ )
558
+ } )
559
+ . map ( Ok ) ,
560
+ )
561
+ {
562
+ let ( rela_path, kind) = item?;
647
563
let file_path = root. join ( gix:: path:: from_bstr ( rela_path) ) ;
648
564
if file_path. file_name ( ) . and_then ( |name| name. to_str ( ) ) == Some ( "Cargo.toml" ) {
649
565
// Keep track of all sub-packages found and also strip out all
@@ -652,16 +568,16 @@ impl<'gctx> PathSource<'gctx> {
652
568
let path = file_path. parent ( ) . unwrap ( ) ;
653
569
if path != pkg_path {
654
570
warn ! ( "subpackage found: {}" , path. display( ) ) ;
655
- paths . retain ( |p| !p. starts_with ( path) ) ;
571
+ files . retain ( |p| !p. starts_with ( path) ) ;
656
572
subpackages_found. push ( path. to_path_buf ( ) ) ;
657
- return Ok ( ( ) ) ;
573
+ continue ;
658
574
}
659
575
}
660
576
661
577
// If this file is part of any other sub-package we've found so far,
662
578
// skip it.
663
579
if subpackages_found. iter ( ) . any ( |p| file_path. starts_with ( p) ) {
664
- return Ok ( ( ) ) ;
580
+ continue ;
665
581
}
666
582
667
583
let is_dir = kind. map_or ( false , |kind| {
@@ -679,21 +595,20 @@ impl<'gctx> PathSource<'gctx> {
679
595
// .git repositories.
680
596
match gix:: open_opts ( & file_path, gix:: open:: Options :: isolated ( ) ) {
681
597
Ok ( sub_repo) => {
682
- let files = source. list_files_gix ( pkg, & sub_repo, filter) ?;
683
- paths. extend ( files) ;
598
+ files. extend ( self . list_files_gix ( pkg, & sub_repo, filter) ?) ;
684
599
}
685
- _ => {
686
- source . walk ( & file_path, paths , false , filter) ?;
600
+ Err ( _ ) => {
601
+ self . walk ( & file_path, & mut files , false , filter) ?;
687
602
}
688
603
}
689
604
} else if ( filter) ( & file_path, is_dir) {
690
605
assert ! ( !is_dir) ;
691
- // We found a file!
692
606
warn ! ( " found {}" , file_path. display( ) ) ;
693
- paths . push ( file_path) ;
607
+ files . push ( file_path) ;
694
608
}
695
- Ok ( ( ) )
696
609
}
610
+
611
+ return Ok ( files) ;
697
612
}
698
613
699
614
/// Lists files relevant to building this package inside this source by
0 commit comments