@@ -31,11 +31,12 @@ public Ingester(IngestOptions options)
31
31
m_options = options ;
32
32
}
33
33
34
- public ( int FileCount , long OutputBytes ) ? Run ( IEnumerable < DirectoryInfo > directories , FileInfo outputFile )
34
+ public ( int FileCount , long OutputBytes ) ? Run ( IEnumerable < DirectoryInfo > directories , FileInfo outputFile , ProgressToken progress = null )
35
35
{
36
36
var didError = false ;
37
37
var sourceFiles = directories
38
38
. Where ( d => d . Exists )
39
+ . AsParallel ( )
39
40
. SelectMany ( d => m_options . FilePatterns . SelectMany ( p =>
40
41
{
41
42
try
@@ -50,15 +51,15 @@ public Ingester(IngestOptions options)
50
51
}
51
52
} ) )
52
53
. Where ( f => ! ShouldSkipFile ( f ) )
53
- . ToDictionary ( o => o . FullName , o => File . ReadLines ( o . FullName ) ) ;
54
+ . ToArray ( ) ;
54
55
55
56
if ( didError )
56
57
{
57
58
Logger . Instance . Error ( "Error collecting files." ) ;
58
59
return null ;
59
60
}
60
61
61
- if ( sourceFiles . Count == 0 )
62
+ if ( sourceFiles . Length == 0 )
62
63
{
63
64
Logger . Instance . Warn ( "No matching files found. Check your filters or directory paths." ) ;
64
65
return ( 0 , 0 ) ;
@@ -71,28 +72,36 @@ public Ingester(IngestOptions options)
71
72
writer . WriteLine ( "// CodeIngest - A CLI tool that merges and processes code files for GPT reviews." ) ;
72
73
writer . WriteLine ( "// Notes: Some code content may have been removed." ) ;
73
74
74
- foreach ( var kvp in sourceFiles )
75
+ for ( var i = 0 ; i < sourceFiles . Length ; i ++ )
75
76
{
76
- var lines = kvp . Value . ToList ( ) ;
77
- var padWidth = lines . Count . ToString ( ) . Length ;
77
+ var sourceFile = sourceFiles [ i ] ;
78
+ if ( progress != null )
79
+ {
80
+ if ( progress . CancelRequested )
81
+ break ; // Caller requested cancellation.
82
+ progress . Progress = ( i + 1.0 ) / sourceFiles . Length ;
83
+ }
84
+
85
+ using var reader = new StreamReader ( sourceFile . OpenRead ( ) , Encoding . UTF8 ) ;
78
86
79
- writer . WriteLine ( $ "// File: { ( m_options . UseFullPaths ? kvp . Key : Path . GetFileName ( kvp . Key ) ) } ") ;
87
+ writer . WriteLine ( $ "// File: { ( m_options . UseFullPaths ? sourceFile . FullName : sourceFile . Name ) } ") ;
80
88
81
89
var lineNumber = 1 ;
82
- foreach ( var line in lines )
90
+ string line ;
91
+ while ( ( line = reader . ReadLine ( ) ) != null )
83
92
{
84
93
if ( ShouldIncludeSourceLine ( line , m_options ) )
85
- writer . WriteLine ( $ "{ lineNumber . ToString ( ) . PadLeft ( padWidth ) } |{ GetCodeLine ( line ) . Trim ( ) } ") ;
94
+ writer . WriteLine ( $ "{ lineNumber . ToString ( ) } |{ GetCodeLine ( line ) . Trim ( ) } ") ;
86
95
87
96
lineNumber ++ ;
88
97
}
89
98
90
99
if ( m_options . Verbose )
91
- Logger . Instance . Warn ( $ "{ kvp . Key } ( { lines . Sum ( o => o . Length ) : N0 } characters -> { lines . Count : N0} lines)") ;
100
+ Logger . Instance . Warn ( $ "{ sourceFile . FullName } processed ( { lineNumber - 1 : N0} lines)") ;
92
101
}
93
102
}
94
103
95
- return ( sourceFiles . Count , outputFile . Length ) ;
104
+ return ( sourceFiles . Length , outputFile . Length ) ;
96
105
}
97
106
98
107
private static bool ShouldSkipFile ( FileInfo f ) =>
0 commit comments