@@ -938,14 +938,68 @@ impl<'a> Scanner<'a> {
938938 // Drain emitter and forward findings to main channel
939939 drop ( emitter. tx ) ; // Close the emitter sender to stop receiving
940940 for finding in emitter. rx . iter ( ) {
941- if let Err ( _ ) = findings_sender. send ( finding) {
941+ if findings_sender. send ( finding) . is_err ( ) {
942942 break ; // Main receiver has been dropped, stop sending
943943 }
944944 }
945945
946946 Ok ( ( ) )
947947 }
948948
949+ /// Simple file discovery for dry-run functionality - doesn't use the full producer-consumer architecture
950+ pub fn discover_files ( & self , roots : & [ PathBuf ] ) -> Vec < PathBuf > {
951+ let mut paths = Vec :: new ( ) ;
952+
953+ // Build glob matcher for include patterns
954+ let include_matcher: Option < globset:: GlobSet > = if !self . config . include_globs . is_empty ( ) {
955+ let mut builder = globset:: GlobSetBuilder :: new ( ) ;
956+ for pattern in & self . config . include_globs {
957+ if let Ok ( glob) = globset:: Glob :: new ( pattern) {
958+ builder. add ( glob) ;
959+ }
960+ }
961+ builder. build ( ) . ok ( )
962+ } else {
963+ None
964+ } ;
965+
966+ for root in roots {
967+ let mut builder = WalkBuilder :: new ( root) ;
968+ builder
969+ . hidden ( false )
970+ . git_ignore ( true )
971+ . git_exclude ( true )
972+ . ignore ( true ) ;
973+
974+ for entry in builder. build ( ) . flatten ( ) {
975+ let md = match entry. metadata ( ) {
976+ Ok ( m) => m,
977+ Err ( _) => continue ,
978+ } ;
979+ if md. is_file ( ) {
980+ if md. len ( ) as usize > self . config . max_file_size {
981+ continue ;
982+ }
983+
984+ let path = entry. into_path ( ) ;
985+
986+ // Apply include glob filtering
987+ if let Some ( ref matcher) = include_matcher {
988+ if !matcher. is_match ( & path) {
989+ continue ;
990+ }
991+ }
992+
993+ // Only include files with supported languages
994+ if Self :: detect_language ( & path) . is_some ( ) {
995+ paths. push ( path) ;
996+ }
997+ }
998+ }
999+ }
1000+ paths
1001+ }
1002+
9491003 pub fn detect_language ( path : & Path ) -> Option < Language > {
9501004 match path
9511005 . extension ( )
@@ -983,10 +1037,10 @@ impl<'a> Scanner<'a> {
9831037 // Create bounded channels for work queue and findings
9841038 const WORK_QUEUE_SIZE : usize = 10_000 ; // Backpressure management
9851039 const FINDINGS_QUEUE_SIZE : usize = 50_000 ; // Large buffer for findings
986-
1040+
9871041 let ( work_sender, work_receiver) = bounded :: < PathBuf > ( WORK_QUEUE_SIZE ) ;
9881042 let ( findings_sender, findings_receiver) = bounded :: < Finding > ( FINDINGS_QUEUE_SIZE ) ;
989-
1043+
9901044 // Progress tracking
9911045 let ( progress_sender, progress_receiver) = if self . config . progress_callback . is_some ( ) {
9921046 let ( tx, rx) = bounded :: < usize > ( 1000 ) ;
@@ -1031,7 +1085,7 @@ impl<'a> Scanner<'a> {
10311085 } ;
10321086
10331087 // Use thread::scope to ensure all threads complete before returning
1034- let findings = thread:: scope ( |s| {
1088+ let findings = thread:: scope ( |s| -> Result < Vec < Finding > > {
10351089 // Spawn producer thread
10361090 let producer_handle = {
10371091 let work_sender = work_sender. clone ( ) ;
@@ -1063,9 +1117,7 @@ impl<'a> Scanner<'a> {
10631117 }
10641118
10651119 // Wait for producer to complete
1066- if let Err ( e) = producer_handle. join ( ) . unwrap ( ) {
1067- return Err ( e) ;
1068- }
1120+ producer_handle. join ( ) . unwrap ( ) ?;
10691121
10701122 // Check consumer result
10711123 consumer_result?;
0 commit comments