1
1
using System . ComponentModel . Design ;
2
2
using System . Diagnostics ;
3
+ using System . IO ;
3
4
using System . Security . AccessControl ;
4
5
5
6
namespace BuildConfigGen
@@ -10,15 +11,17 @@ internal class EnsureUpdateModeVerifier
10
11
// if any changes would be made to output, verification should fail
11
12
// check the contents of VerifyErrors for verification errors
12
13
13
- private readonly bool verifyOnly ;
14
+ private bool verifyState ;
15
+ private readonly bool verifyFromConstructor ;
14
16
private List < string > VerifyErrors = new List < string > ( ) ;
15
17
internal Dictionary < string , string > CopiedFilesToCheck = new Dictionary < string , string > ( ) ;
16
18
internal Dictionary < string , string > RedirectedToTempl = new Dictionary < string , string > ( ) ;
17
19
private HashSet < string > tempsToKeep = new HashSet < string > ( ) ;
18
20
19
21
public EnsureUpdateModeVerifier ( bool verifyOnly )
20
22
{
21
- this . verifyOnly = verifyOnly ;
23
+ this . verifyState = verifyOnly ;
24
+ this . verifyFromConstructor = verifyOnly ;
22
25
}
23
26
24
27
public IEnumerable < string > GetVerifyErrors ( bool skipContentCheck )
@@ -30,7 +33,6 @@ public IEnumerable<string> GetVerifyErrors(bool skipContentCheck)
30
33
31
34
if ( ! skipContentCheck )
32
35
{
33
-
34
36
foreach ( var r in CopiedFilesToCheck )
35
37
{
36
38
string ? sourceFile ;
@@ -90,9 +92,9 @@ public void CleanupTempFiles()
90
92
}
91
93
}
92
94
93
- if ( count > 0 && ! verifyOnly )
95
+ if ( count > 0 && ! verifyFromConstructor )
94
96
{
95
- throw new Exception ( "Expected RedirectedToTemp to be empty when !verifyOnly " ) ;
97
+ throw new Exception ( "Expected RedirectedToTemp to be empty when !verifyFromConstructor " ) ;
96
98
}
97
99
}
98
100
finally
@@ -105,6 +107,8 @@ public void CleanupTempFiles()
105
107
106
108
internal void Copy ( string sourceFileName , string destFileName , bool overwrite )
107
109
{
110
+ bool verifyOnly = UseVerifyOnlyForFile ( destFileName ) ;
111
+
108
112
if ( verifyOnly )
109
113
{
110
114
if ( File . Exists ( destFileName ) )
@@ -138,6 +142,16 @@ internal void Copy(string sourceFileName, string destFileName, bool overwrite)
138
142
139
143
internal void Move ( string sourceFileName , string destFileName )
140
144
{
145
+ bool verifyOnlySource = UseVerifyOnlyForFile ( sourceFileName ) ;
146
+ bool verifyOnlyDest = UseVerifyOnlyForFile ( destFileName ) ;
147
+
148
+ if ( verifyOnlySource != verifyOnlyDest )
149
+ {
150
+ throw new Exception ( $ "BUG: both source and dest must be unconditional path or not sourceFileName={ sourceFileName } destFileName={ destFileName } ") ;
151
+ }
152
+
153
+ var verifyOnly = verifyOnlySource || verifyOnlyDest ;
154
+
141
155
if ( verifyOnly )
142
156
{
143
157
// verification won't pass if we encounter a move
@@ -160,6 +174,8 @@ internal void Move(string sourceFileName, string destFileName)
160
174
161
175
internal void WriteAllText ( string path , string contents , bool suppressValidationErrorIfTargetPathDoesntExist )
162
176
{
177
+ bool verifyOnly = UseVerifyOnlyForFile ( path ) ;
178
+
163
179
if ( verifyOnly )
164
180
{
165
181
if ( File . Exists ( path ) )
@@ -205,6 +221,8 @@ private string NormalizeFile(string file)
205
221
206
222
internal void DirectoryCreateDirectory ( string path , bool suppressValidationErrorIfTargetPathDoesntExist )
207
223
{
224
+ bool verifyOnly = UseVerifyOnlyForPath ( path ) ;
225
+
208
226
if ( verifyOnly )
209
227
{
210
228
if ( ! Directory . Exists ( path ) )
@@ -228,6 +246,8 @@ internal void DirectoryCreateDirectory(string path, bool suppressValidationError
228
246
229
247
internal string FileReadAllText ( string filePath )
230
248
{
249
+ bool verifyOnly = UseVerifyOnlyForFile ( filePath ) ;
250
+
231
251
if ( verifyOnly )
232
252
{
233
253
string targetFile = ResolveFile ( filePath ) ;
@@ -240,8 +260,10 @@ internal string FileReadAllText(string filePath)
240
260
}
241
261
}
242
262
243
- internal string [ ] FileReadAllLines ( string filePath )
263
+ internal string [ ] FileReadAllLines ( string filePath )
244
264
{
265
+ bool verifyOnly = UseVerifyOnlyForFile ( filePath ) ;
266
+
245
267
if ( verifyOnly )
246
268
{
247
269
string targetFile = ResolveFile ( filePath ) ;
@@ -263,7 +285,7 @@ internal bool FilesEqual(string sourcePath, string targetPath)
263
285
264
286
private string ResolveFile ( string filePath )
265
287
{
266
- if ( ! verifyOnly )
288
+ if ( ! UseVerifyOnlyForFile ( filePath ) )
267
289
{
268
290
return filePath ;
269
291
}
@@ -295,20 +317,138 @@ private string ResolveFile(string filePath)
295
317
296
318
internal void DeleteDirectoryRecursive ( string path )
297
319
{
298
- if ( verifyOnly )
320
+ bool verify = UseVerifyOnlyForPath ( path ) ;
321
+
322
+ if ( verify )
299
323
{
300
- if ( Directory . Exists ( path ) )
324
+ if ( Directory . Exists ( path ) )
301
325
{
302
326
VerifyErrors . Add ( $ "Expected directory { path } to not exist") ;
303
327
}
304
328
}
305
329
else
306
330
{
307
- if ( Directory . Exists ( path ) )
331
+ if ( Directory . Exists ( path ) )
308
332
{
309
333
Directory . Delete ( path , true ) ;
310
334
}
311
335
}
312
336
}
337
+
338
+ private bool UseVerifyOnlyForFile ( string file )
339
+ {
340
+ return UseVerifyOnlyInternal ( file , true ) ;
341
+ }
342
+
343
+ private bool UseVerifyOnlyForPath ( string path )
344
+ {
345
+ return UseVerifyOnlyInternal ( path , false ) ;
346
+ }
347
+
348
+ private bool UseVerifyOnlyInternal ( string path , bool trueForFile )
349
+ {
350
+ EnsureState ( ) ;
351
+
352
+ /*
353
+ // if verifyOnly state
354
+ if (verifyState)
355
+ {
356
+ return true;
357
+ }*/
358
+
359
+ // if !verifyOnly was passed to constructor, unconditional writes everywhere
360
+ if ( ! verifyFromConstructor )
361
+ {
362
+ return false ;
363
+ }
364
+
365
+ // if uncondo
366
+ if ( allowedUnconditionalPath is null )
367
+ {
368
+ return verifyState ;
369
+ }
370
+
371
+ if ( trueForFile ? IsSubFile ( allowedUnconditionalPath , path ) : IsSubPath ( allowedUnconditionalPath , path ) )
372
+ {
373
+ return false ;
374
+ }
375
+ else
376
+ {
377
+ return true ;
378
+ }
379
+ }
380
+
381
+ string ? allowedUnconditionalPath ;
382
+
383
+ internal void StartUnconditionalWrites ( string allowedUnconditionalPath )
384
+ {
385
+ EnsureState ( ) ;
386
+
387
+ if ( verifyState != verifyFromConstructor )
388
+ {
389
+ throw new Exception ( $ "BUG: expected verifyState { verifyState } == verifyFromConstructor { verifyFromConstructor } ") ;
390
+ }
391
+
392
+ if ( ! verifyFromConstructor )
393
+ {
394
+ return ;
395
+ }
396
+
397
+ verifyState = false ;
398
+ this . allowedUnconditionalPath = allowedUnconditionalPath ;
399
+ }
400
+
401
+ internal void ResumeWriteBehavior ( )
402
+ {
403
+ EnsureState ( ) ;
404
+
405
+ if ( ! verifyFromConstructor )
406
+ {
407
+ return ;
408
+ }
409
+
410
+ verifyState = verifyFromConstructor ;
411
+ this . allowedUnconditionalPath = null ;
412
+ }
413
+
414
+ private void EnsureState ( )
415
+ {
416
+ if ( ! verifyFromConstructor && verifyState )
417
+ {
418
+ throw new Exception ( "BUG: verifyState cannot be true if verifyFromConstructor is false" ) ;
419
+ }
420
+
421
+ if ( verifyFromConstructor )
422
+ {
423
+ if ( this . allowedUnconditionalPath is null && ! verifyState )
424
+ {
425
+ throw new Exception ( $ "BUG: expected allowedUnconditionalPath={ allowedUnconditionalPath } to be not null when !verifyState=={ ! verifyState } ") ;
426
+ }
427
+ }
428
+ else
429
+ {
430
+ if ( this . allowedUnconditionalPath is not null )
431
+ {
432
+ throw new Exception ( $ "BUG: expected allowedUnconditionalPath={ allowedUnconditionalPath } to be null") ;
433
+ }
434
+ }
435
+ }
436
+
437
+ // generaetd by copilot 20240926
438
+ static bool IsSubPath ( string mainPath , string subPath )
439
+ {
440
+ var mainDirectory = new DirectoryInfo ( mainPath ) . FullName ;
441
+ var subDirectory = new DirectoryInfo ( subPath ) . FullName ;
442
+
443
+ return subDirectory . StartsWith ( mainDirectory , StringComparison . OrdinalIgnoreCase ) ;
444
+ }
445
+
446
+ static bool IsSubFile ( string mainPath , string subFile )
447
+ {
448
+ var mainDirectory = new DirectoryInfo ( mainPath ) . FullName ;
449
+ var subDirectory = new FileInfo ( subFile ) . FullName ;
450
+
451
+ return subDirectory . StartsWith ( mainDirectory , StringComparison . OrdinalIgnoreCase ) ;
452
+ }
313
453
}
314
454
}
0 commit comments