1
+ // Code authored by Dean Edis (DeanTheCoder).
2
+ // Anyone is free to copy, modify, use, compile, or distribute this software,
3
+ // either in source code form or as a compiled binary, for any non-commercial
4
+ // purpose.
5
+ //
6
+ // If you modify the code, please retain this copyright header,
7
+ // and consider contributing back to the repository or letting us know
8
+ // about your modifications. Your contributions are valued!
9
+ //
10
+ // THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND.
11
+ using System . Text ;
12
+
13
+ namespace CodeIngestCmd ;
14
+
15
+ internal class Ingester
16
+ {
17
+ private static string [ ] SymbolsToCollapse { get ; } = new [ ]
18
+ {
19
+ "<" , "<=" , "=" , "==" , "=>" , ">" , "!=" , "(" , ")" , "{" , "}" , "[" , "]" , "-" , "+" , "*" , "&" , "%" , "/" , "<<" , ">>" , ";" , "," , "||" , "|" , ":" , "?" , "|"
20
+ } ;
21
+
22
+ public void Ingest ( IngestOptions options )
23
+ {
24
+ var sourceFiles = options . Directories
25
+ . Where ( d => d . Exists )
26
+ . SelectMany ( d => options . Patterns . SelectMany ( p =>
27
+ {
28
+ try
29
+ {
30
+ return d . GetFiles ( p , SearchOption . AllDirectories ) ;
31
+ }
32
+ catch ( Exception ex )
33
+ {
34
+ Console . WriteLine ( $ "Warning: Failed to read directory { d . FullName } : { ex . Message } ") ;
35
+ return Array . Empty < FileInfo > ( ) ;
36
+ }
37
+ } ) )
38
+ . Where ( f => ! ShouldSkipFile ( f ) )
39
+ . ToDictionary ( o => o . FullName , o => File . ReadLines ( o . FullName ) ) ;
40
+
41
+ if ( sourceFiles . Count == 0 )
42
+ {
43
+ Console . WriteLine ( "No matching files found. Check your filters or directory paths." ) ;
44
+ return ;
45
+ }
46
+
47
+ using ( var fileStream = options . OutputFile . Open ( FileMode . Create ) )
48
+ using ( var writer = new StreamWriter ( fileStream , Encoding . UTF8 ) )
49
+ {
50
+ writer . NewLine = "\n " ;
51
+ writer . WriteLine ( "// CodeIngest - A CLI tool that merges and processes code files for GPT reviews." ) ;
52
+ writer . WriteLine ( "// Notes: Some code content may have been removed." ) ;
53
+
54
+ foreach ( var kvp in sourceFiles )
55
+ {
56
+ var lines = kvp . Value . ToList ( ) ;
57
+ var padWidth = lines . Count . ToString ( ) . Length ;
58
+
59
+ writer . WriteLine ( $ "// File: { ( options . UseFullPaths ? kvp . Key : Path . GetFileName ( kvp . Key ) ) } ") ;
60
+
61
+ var lineNumber = 1 ;
62
+ foreach ( var line in lines )
63
+ {
64
+ if ( ShouldIncludeSourceLine ( line ) )
65
+ writer . WriteLine ( $ "{ lineNumber . ToString ( ) . PadLeft ( padWidth ) } |{ GetCodeLine ( line ) . Trim ( ) } ") ;
66
+
67
+ lineNumber ++ ;
68
+ }
69
+
70
+ if ( options . Verbose )
71
+ Console . WriteLine ( $ "{ kvp . Key } ({ lines . Sum ( o => o . Length ) : N0} characters -> { lines . Count : N0} lines)") ;
72
+ }
73
+ }
74
+
75
+ Console . WriteLine ( "CodeIngest completed successfully." ) ;
76
+ Console . WriteLine ( $ "Processed { sourceFiles . Count : N0} files, producing { options . OutputFile . Length : N0} bytes.") ;
77
+ }
78
+
79
+ private static bool ShouldSkipFile ( FileInfo f ) =>
80
+ new [ ]
81
+ {
82
+ "resx" , ".g." , ".designer." , "\\ obj\\ " , "/obj/" , "\\ bin\\ " , "/bin/" , "assemblyinfo.cs" , "/." , "\\ ."
83
+ } . Any ( o => f . FullName . Contains ( o , StringComparison . OrdinalIgnoreCase ) ) ;
84
+
85
+ private static bool ShouldIncludeSourceLine ( string s )
86
+ {
87
+ if ( string . IsNullOrWhiteSpace ( s ) )
88
+ return false ;
89
+ if ( s . StartsWith ( "using" ) || s . StartsWith ( "#include" ) || s . StartsWith ( "#pragma" ) )
90
+ return false ;
91
+
92
+ var trimmed = s . Trim ( ) ;
93
+ if ( trimmed . StartsWith ( "//" ) )
94
+ return false ;
95
+ if ( trimmed . StartsWith ( "/*" ) && trimmed . EndsWith ( "*/" ) )
96
+ return false ;
97
+ if ( trimmed . StartsWith ( "namespace" ) )
98
+ return false ;
99
+ return true ;
100
+ }
101
+
102
+ private static string GetCodeLine ( string line )
103
+ {
104
+ var commentIndex = line . IndexOf ( "//" , StringComparison . Ordinal ) ;
105
+ if ( commentIndex >= 0 )
106
+ line = line [ ..commentIndex ] ;
107
+
108
+ foreach ( var expr in SymbolsToCollapse )
109
+ line = line . Replace ( $ "{ expr } ", expr ) . Replace ( $ " { expr } ", expr ) ;
110
+
111
+ while ( line . Contains ( " " ) )
112
+ line = line . Replace ( " " , " " ) ;
113
+
114
+ return line ;
115
+ }
116
+ }
0 commit comments