11using System ;
2+ using System . Collections . Generic ;
23using System . Diagnostics ;
4+ using System . Drawing ;
5+ using System . IO ;
6+ using System . Linq ;
7+ using System . Text . RegularExpressions ;
8+ using System . Threading ;
39using Cirilla . Core . Models ;
410using CommandLine ;
511
612namespace GMDTool
713{
814 class Program
915 {
16+ public record UpdatedEntry ( string Key , string OldValue , string NewValue ) ;
17+
1018 static int Main ( string [ ] args )
1119 {
12- int res = Parser . Default . ParseArguments < PrintOptions > ( args )
20+ int res = Parser . Default . ParseArguments < PrintOptions , SearchOptions , ReplaceOptions > ( args )
1321 . MapResult (
14- ( PrintOptions opts ) => RunPrintAndReturnExitCode ( opts ) ,
15- errs => 1 ) ;
22+ ( PrintOptions opts ) => Print ( opts ) ,
23+ ( SearchOptions opts ) => Search ( opts ) ,
24+ ( ReplaceOptions opts ) => Replace ( opts ) ,
25+ errs => 1 ) ;
1626
1727 if ( Debugger . IsAttached )
28+ {
29+ Console . WriteLine ( "Debugger detected. Press enter to exit..." ) ;
1830 Console . ReadLine ( ) ;
31+ }
1932
2033 return res ;
2134 }
2235
23- private static int RunPrintAndReturnExitCode ( PrintOptions opts )
36+ private static void PrintEntry ( IGMD_Entry entry )
37+ {
38+ string key = "(NO_KEY)" ;
39+
40+ if ( entry as GMD_Entry is var x && x != null )
41+ key = x . Key ;
42+
43+ Colorful . Console . Write ( key , Color . Cyan ) ;
44+ Colorful . Console . Write ( ":" ) ;
45+ Colorful . Console . WriteLine ( entry . Value , Color . Orange ) ;
46+ }
47+
48+ private static int Print ( PrintOptions opts )
2449 {
2550 GMD gmd ;
2651
@@ -38,17 +63,127 @@ private static int RunPrintAndReturnExitCode(PrintOptions opts)
3863
3964 foreach ( var entry in gmd . Entries )
4065 {
41- string key = "\" \" " ;
42- string value = '"' + entry . Value + '"' ;
66+ PrintEntry ( entry ) ;
67+ }
68+
69+ return 0 ;
70+ }
71+
72+ private static int Search ( SearchOptions opts )
73+ {
74+ string [ ] files = Directory . GetFiles ( opts . Input , "*.gmd" , SearchOption . AllDirectories ) ;
75+
76+ foreach ( var file in files )
77+ {
78+ var matches = new List < IGMD_Entry > ( ) ;
79+
80+ try
81+ {
82+ var gmd = new GMD ( file ) ;
83+
84+ foreach ( var entry in gmd . Entries )
85+ {
86+ if ( opts . Search . Any ( x => Regex . IsMatch ( entry . Value , x ) ) )
87+ matches . Add ( entry ) ;
88+ }
89+
90+ if ( matches . Count > 0 )
91+ {
92+ Colorful . Console . WriteLine ( file , Color . Green ) ;
93+ foreach ( var entry in matches )
94+ PrintEntry ( entry ) ;
95+ Console . WriteLine ( ) ;
96+ }
97+ }
98+ catch ( Exception ex )
99+ {
100+ Console . WriteLine ( "Error: " + ex ) ;
101+ }
102+ }
103+
104+ return 0 ;
105+ }
106+
107+ private static int Replace ( ReplaceOptions opts )
108+ {
109+
110+ string [ ] files = Directory . GetFiles ( opts . Input , "*.gmd" , SearchOption . AllDirectories ) ;
111+
112+ int itemCount = files . Length ;
113+ int processedCount = 0 ;
114+ int changedFilesCount = 0 ;
115+ int changedValuesCount = 0 ;
116+ var sw = Stopwatch . StartNew ( ) ;
117+
118+ Console . WriteLine ( "Total files: " + itemCount ) ;
119+ Console . WriteLine ( "Preview mode: " + opts . Preview ) ;
120+
121+ foreach ( var file in files )
122+ {
123+ try
124+ {
125+ var changes = new List < UpdatedEntry > ( ) ;
126+ var gmd = new GMD ( file ) ;
127+
128+ foreach ( var entry in gmd . Entries )
129+ {
130+ string val = Regex . Replace ( entry . Value , opts . Search , opts . ReplaceWith ) ;
131+ if ( entry . Value != val )
132+ {
133+ string key = "(NO_KEY)" ;
134+
135+ if ( entry as GMD_Entry is var x && x != null )
136+ key = x . Key ;
137+
138+ changes . Add ( new UpdatedEntry ( key , entry . Value , val ) ) ;
139+ entry . Value = val ;
140+ }
141+ }
142+
143+ if ( changes . Count > 0 )
144+ {
145+ string relPath = Path . GetRelativePath ( opts . Input , file ) ;
146+ string dest = Path . Join ( opts . Output , relPath ) ;
43147
44- if ( entry as GMD_Entry is var x && x != null )
45- key = '"' + x . Key + '"' ;
46- else if ( opts . IncludeAll == false )
47- continue ; // If entry has no key and IncludeAll is false then don't print it
148+ Colorful . Console . Write ( file , Color . Red ) ;
149+ Console . Write ( " -> " ) ;
150+ Colorful . Console . WriteLine ( dest , Color . LightGreen ) ;
151+ Colorful . Console . WriteLine ( "Changes: " + changes . Count , Color . Yellow ) ;
48152
49- Console . WriteLine ( key + " = " + value ) ;
153+ foreach ( var change in changes )
154+ {
155+ Colorful . Console . WriteLine ( change . Key , Color . Cyan ) ;
156+ Colorful . Console . Write ( change . OldValue , Color . Orange ) ;
157+ Console . Write ( " -> " ) ;
158+ Colorful . Console . WriteLine ( change . NewValue , Color . Green ) ;
159+ Console . WriteLine ( ) ;
160+ }
161+
162+ if ( ! opts . Preview )
163+ {
164+ string ? dir = Path . GetDirectoryName ( dest ) ;
165+ if ( dir != null ) Directory . CreateDirectory ( dir ) ;
166+ gmd . Save ( dest ) ;
167+ }
168+ }
169+ }
170+ catch ( Exception ex )
171+ {
172+ Console . WriteLine ( $ "Error { ex } in '{ file } '") ;
173+ }
174+
175+ Interlocked . Increment ( ref processedCount ) ;
50176 }
51177
178+ sw . Stop ( ) ;
179+
180+ Console . WriteLine ( ) ;
181+ Console . WriteLine ( "Finished!" ) ;
182+ Console . WriteLine ( "Processed: " + processedCount ) ;
183+ Console . WriteLine ( "Changed files: " + changedFilesCount ) ;
184+ Console . WriteLine ( "Changed values: " + changedValuesCount ) ;
185+ Console . WriteLine ( "Elapsed: " + sw . Elapsed ) ;
186+
52187 return 0 ;
53188 }
54189 }
0 commit comments