1
1
namespace CodeIngest ;
2
2
3
- internal static class Program
3
+ static class Program
4
4
{
5
5
private static void Main ( string [ ] args )
6
6
{
7
7
// Getting directory argument from the command line (Report error if none found).
8
- if ( args . Length != 2 )
8
+ if ( args . Length < 2 || args . Any ( a => a is "-h" or "--help" or "/?" ) )
9
9
{
10
- Console . WriteLine ( "Usage: CodeIngest <directory> <output.cs>" ) ;
10
+ ShowUsage ( ) ;
11
11
return ;
12
12
}
13
+
14
+ var outputFile = new FileInfo ( args [ ^ 1 ] ) ;
15
+ var patterns = new List < string > ( ) ;
16
+ var directories = new List < DirectoryInfo > ( ) ;
17
+
18
+ for ( var i = 0 ; i < args . Length - 1 ; i ++ )
19
+ {
20
+ if ( args [ i ] . Contains ( '*' ) )
21
+ patterns . AddRange ( args [ i ] . Split ( ';' , StringSplitOptions . RemoveEmptyEntries ) ) ;
22
+ else
23
+ directories . Add ( new DirectoryInfo ( args [ i ] ) ) ;
24
+ }
25
+
26
+ if ( directories . Count == 0 )
27
+ directories . Add ( new DirectoryInfo ( "." ) ) ;
28
+
29
+ if ( patterns . Count == 0 )
30
+ patterns . Add ( "*.cs" ) ;
31
+
32
+ // Recurse directory to find all source files.
33
+ var sourceFiles = directories
34
+ . Where ( d => d . Exists )
35
+ . SelectMany ( d => patterns . SelectMany ( p =>
36
+ {
37
+ try
38
+ {
39
+ return d . GetFiles ( p , SearchOption . AllDirectories ) ;
40
+ }
41
+ catch ( Exception ex )
42
+ {
43
+ Console . WriteLine ( $ "Warning: Failed to read directory { d . FullName } : { ex . Message } ") ;
44
+ return [ ] ;
45
+ }
46
+ } ) )
47
+ . Where ( f => ! ShouldSkipFile ( f ) )
48
+ . ToDictionary ( o => o . Name , o => File . ReadLines ( o . FullName ) ) ;
13
49
14
- var sourceDirectory = new DirectoryInfo ( args [ 0 ] ) ;
15
-
16
- // Check directory exists (Report error if not found).
17
- if ( ! sourceDirectory . Exists )
50
+ if ( sourceFiles . Count == 0 )
18
51
{
19
- Console . WriteLine ( "Directory not found: " + sourceDirectory . FullName ) ;
52
+ Console . WriteLine ( "No matching files found. Check your filters or directory paths." ) ;
20
53
return ;
21
54
}
22
-
23
- // Recurse directory to file all .cs files.
24
- var sourceFiles =
25
- sourceDirectory
26
- . GetFiles ( "*.cs" , SearchOption . AllDirectories )
27
- . Where ( f => ! ShouldSkipFile ( f ) )
28
- . ToDictionary ( o => o . FullName , o => File . ReadLines ( o . FullName ) ) ;
29
-
55
+
30
56
// Write header.
31
- var outputFile = new FileInfo ( args [ 1 ] ) ;
32
57
using ( var fileStream = outputFile . Open ( FileMode . Create ) )
33
58
using ( var writer = new StreamWriter ( fileStream ) )
34
59
{
35
60
{
36
- writer . WriteLine (
37
- "// CodeIngest Source Dump - A CLI tool that merges and processes code files for GPT reviews." ) ;
38
- writer . WriteLine ( "// Notes: Comments, namespaces, and using statements removed to reduce noise." ) ;
61
+ writer . WriteLine ( "// CodeIngest Source Dump - A CLI tool that merges and processes code files for GPT reviews." ) ;
62
+ writer . WriteLine ( "// Notes: Some code content may have been removed." ) ;
39
63
40
64
// Combine files into a single output file.
41
65
foreach ( var kvp in sourceFiles )
42
66
{
43
67
var lines = kvp . Value . ToList ( ) ; // Force evaluation to count
44
- var lineCount = lines . Count ;
45
- var padWidth = lineCount . ToString ( ) . Length ;
68
+ var padWidth = lines . Count . ToString ( ) . Length ;
46
69
47
- writer . WriteLine ( $ "// File: { kvp . Key } ( { lineCount : N0 } lines) ") ;
70
+ writer . WriteLine ( $ "// File: { kvp . Key } ") ;
48
71
49
72
var lineNumber = 1 ;
50
73
foreach ( var line in lines )
51
74
{
52
75
if ( ShouldIncludeSourceLine ( line ) )
53
- writer . WriteLine ( $ "{ lineNumber . ToString ( ) . PadLeft ( padWidth ) } | { line . Trim ( ) } ") ;
76
+ writer . WriteLine ( $ "{ lineNumber . ToString ( ) . PadLeft ( padWidth ) } | { GetCodeLine ( line ) . Trim ( ) } ") ;
54
77
55
78
lineNumber ++ ;
56
79
}
@@ -63,8 +86,31 @@ private static void Main(string[] args)
63
86
Console . WriteLine ( $ "Processed { sourceFiles . Count : N0} files, producing { outputFile . Length : N0} bytes.") ;
64
87
}
65
88
89
+ private static void ShowUsage ( )
90
+ {
91
+ Console . WriteLine ( "Usage:" ) ;
92
+ Console . WriteLine ( " CodeIngest [<directory> ...] [*.ext1;*.ext2] <output.code>" ) ;
93
+ Console . WriteLine ( ) ;
94
+ Console . WriteLine ( "See:" ) ;
95
+ Console . WriteLine ( " https://github.com/deanthecoder/CodeIngest" ) ;
96
+ Console . WriteLine ( ) ;
97
+ Console . WriteLine ( "Examples:" ) ;
98
+ Console . WriteLine ( " CodeIngest MyProject Out.cs" ) ;
99
+ Console . WriteLine ( " CodeIngest Src1 Src2 *.cs;*.txt Dump.txt" ) ;
100
+ Console . WriteLine ( " CodeIngest *.cs;*.cpp SourceDump.code" ) ;
101
+ Console . WriteLine ( ) ;
102
+ Console . WriteLine ( "Note:" ) ;
103
+ Console . WriteLine ( " - The output file will be overwritten if it already exists." ) ;
104
+ Console . WriteLine ( " - If no directory is specified, the current directory is used." ) ;
105
+ Console . WriteLine ( " - If no file filter is specified, *.cs is used by default." ) ;
106
+ }
107
+
66
108
private static bool ShouldSkipFile ( FileInfo f ) =>
67
- new [ ] { "resx" , ".g." , ".designer." , "\\ obj\\ " , "/obj/" , "\\ bin\\ " , "/bin/" , "assemblyinfo.cs" , "/." , "\\ ." } . Any ( o => f . FullName . Contains ( o , StringComparison . OrdinalIgnoreCase ) ) ;
109
+ new [ ]
110
+ {
111
+ "resx" , ".g." , ".designer." , "\\ obj\\ " , "/obj/" , "\\ bin\\ " , "/bin/" , "assemblyinfo.cs" , "/." , "\\ ."
112
+ }
113
+ . Any ( o => f . FullName . Contains ( o , StringComparison . OrdinalIgnoreCase ) ) ;
68
114
69
115
private static bool ShouldIncludeSourceLine ( string s )
70
116
{
@@ -80,4 +126,11 @@ private static bool ShouldIncludeSourceLine(string s)
80
126
return false ;
81
127
return true ;
82
128
}
129
+
130
+ private static string GetCodeLine ( string line )
131
+ {
132
+ // Strip all comments.
133
+ var commentIndex = line . IndexOf ( "//" , StringComparison . Ordinal ) ;
134
+ return commentIndex >= 0 ? line [ ..commentIndex ] : line ;
135
+ }
83
136
}
0 commit comments