@@ -292,7 +292,9 @@ public IEnumerable<string> EnumeratePSFiles()
292
292
return Enumerable . Empty < string > ( ) ;
293
293
}
294
294
295
- return this . RecursivelyEnumerateFiles ( WorkspacePath ) ;
295
+ var foundFiles = new List < string > ( ) ;
296
+ this . RecursivelyEnumerateFiles ( WorkspacePath , ref foundFiles ) ;
297
+ return foundFiles ;
296
298
}
297
299
298
300
#endregion
@@ -301,109 +303,95 @@ public IEnumerable<string> EnumeratePSFiles()
301
303
302
304
/// <summary>
303
305
/// Find PowerShell files recursively down from a given directory path.
304
- /// Currently returns files in depth-first order.
306
+ /// Currently collects files in depth-first order.
305
307
/// Directory.GetFiles(folderPath, pattern, SearchOption.AllDirectories) would provide this,
306
308
/// but a cycle in the filesystem will cause that to enter an infinite loop.
307
309
/// </summary>
308
- /// <param name="folderPath">The absolute path of the base folder to search.</param>
309
- /// <returns>
310
- /// All PowerShell files in the recursive directory hierarchy under the given base directory, up to 64 directories deep.
311
- /// </returns>
312
- private IEnumerable < string > RecursivelyEnumerateFiles ( string folderPath )
310
+ /// <param name="folderPath">The path of the current directory to find files in</param>
311
+ /// <param name="foundFiles">The accumulator for files found so far.</param>
312
+ /// <param name="currDepth">The current depth of the recursion from the original base directory.</param>
313
+ private void RecursivelyEnumerateFiles ( string folderPath , ref List < string > foundFiles , int currDepth = 0 )
313
314
{
314
- var foundFiles = new List < string > ( ) ;
315
- var dirStack = new Stack < string > ( ) ;
316
-
317
- // Kick the search off with the base directory
318
- dirStack . Push ( folderPath ) ;
319
-
320
315
const int recursionDepthLimit = 64 ;
321
- while ( dirStack . Any ( ) )
322
- {
323
- string currDir = dirStack . Pop ( ) ;
324
-
325
- // Look for any PowerShell files in the current directory
326
- foreach ( string pattern in s_psFilePatterns )
327
- {
328
- string [ ] psFiles ;
329
- try
330
- {
331
- psFiles = Directory . GetFiles ( currDir , pattern , SearchOption . TopDirectoryOnly ) ;
332
- }
333
- catch ( DirectoryNotFoundException e )
334
- {
335
- this . logger . WriteHandledException (
336
- $ "Could not enumerate files in the path '{ currDir } ' due to it being an invalid path",
337
- e ) ;
338
-
339
- continue ;
340
- }
341
- catch ( PathTooLongException e )
342
- {
343
- this . logger . WriteHandledException (
344
- $ "Could not enumerate files in the path '{ currDir } ' due to the path being too long",
345
- e ) ;
346
-
347
- continue ;
348
- }
349
- catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
350
- {
351
- this . logger . WriteHandledException (
352
- $ "Could not enumerate files in the path '{ currDir } ' due to the path not being accessible",
353
- e ) ;
354
-
355
- continue ;
356
- }
357
-
358
- foundFiles . AddRange ( psFiles ) ;
359
- }
360
-
361
- // Prevent unbounded recursion here
362
- // If we get too deep, keep processing but go no deeper
363
- if ( dirStack . Count >= recursionDepthLimit )
364
- {
365
- this . logger . Write ( LogLevel . Warning , $ "Recursion depth limit hit for path { folderPath } ") ;
366
- continue ;
367
- }
368
316
369
- // Add the recursive directories to search next
370
- string [ ] subDirs ;
317
+ // Look for any PowerShell files in the current directory
318
+ foreach ( string pattern in s_psFilePatterns )
319
+ {
320
+ string [ ] psFiles ;
371
321
try
372
322
{
373
- subDirs = Directory . GetDirectories ( currDir ) ;
323
+ psFiles = Directory . GetFiles ( folderPath , pattern , SearchOption . TopDirectoryOnly ) ;
374
324
}
375
325
catch ( DirectoryNotFoundException e )
376
326
{
377
327
this . logger . WriteHandledException (
378
- $ "Could not enumerate directories in the path '{ currDir } ' due to it being an invalid path",
328
+ $ "Could not enumerate files in the path '{ folderPath } ' due to it being an invalid path",
379
329
e ) ;
380
330
381
331
continue ;
382
332
}
383
333
catch ( PathTooLongException e )
384
334
{
385
335
this . logger . WriteHandledException (
386
- $ "Could not enumerate directories in the path '{ currDir } ' due to the path being too long",
336
+ $ "Could not enumerate files in the path '{ folderPath } ' due to the path being too long",
387
337
e ) ;
388
338
389
339
continue ;
390
340
}
391
341
catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
392
342
{
393
343
this . logger . WriteHandledException (
394
- $ "Could not enumerate directories in the path '{ currDir } ' due to the path not being accessible",
344
+ $ "Could not enumerate files in the path '{ folderPath } ' due to the path not being accessible",
395
345
e ) ;
396
346
397
347
continue ;
398
348
}
399
349
400
- foreach ( string subDir in subDirs )
401
- {
402
- dirStack . Push ( subDir ) ;
403
- }
350
+ foundFiles . AddRange ( psFiles ) ;
404
351
}
405
352
406
- return foundFiles ;
353
+ // Prevent unbounded recursion here
354
+ if ( currDepth >= recursionDepthLimit )
355
+ {
356
+ this . logger . Write ( LogLevel . Warning , $ "Recursion depth limit hit for path { folderPath } ") ;
357
+ return ;
358
+ }
359
+
360
+ // Add the recursive directories to search next
361
+ string [ ] subDirs ;
362
+ try
363
+ {
364
+ subDirs = Directory . GetDirectories ( folderPath ) ;
365
+ }
366
+ catch ( DirectoryNotFoundException e )
367
+ {
368
+ this . logger . WriteHandledException (
369
+ $ "Could not enumerate directories in the path '{ folderPath } ' due to it being an invalid path",
370
+ e ) ;
371
+
372
+ return ;
373
+ }
374
+ catch ( PathTooLongException e )
375
+ {
376
+ this . logger . WriteHandledException (
377
+ $ "Could not enumerate directories in the path '{ folderPath } ' due to the path being too long",
378
+ e ) ;
379
+
380
+ return ;
381
+ }
382
+ catch ( Exception e ) when ( e is SecurityException || e is UnauthorizedAccessException )
383
+ {
384
+ this . logger . WriteHandledException (
385
+ $ "Could not enumerate directories in the path '{ folderPath } ' due to the path not being accessible",
386
+ e ) ;
387
+
388
+ return ;
389
+ }
390
+
391
+ foreach ( string subDir in subDirs )
392
+ {
393
+ RecursivelyEnumerateFiles ( subDir , ref foundFiles , currDepth : currDepth + 1 ) ;
394
+ }
407
395
}
408
396
409
397
/// <summary>
0 commit comments