-
Notifications
You must be signed in to change notification settings - Fork 26
Refactor DirectoryInfoExtensions.FindFiles to Reduce Cognitive Complexity #570
Copy link
Copy link
Closed
Copy link
Labels
C#C# related codeC# related codeenhancementNew feature or requestNew feature or requestgood first issueGood for newcomersGood for newcomershacktoberfest-acceptedhelp wantedExtra attention is neededExtra attention is neededrefactoringRefactoring codeRefactoring codereliability
Description
What version of FlowSynx?
1.2.1
Description
The FindFiles method currently exceeds the allowed Cognitive Complexity limit (16 > 15). This issue aims to refactor the method to improve readability, maintainability, and adherence to code quality standards.
File: /plugins/FlowSynx.Plugins.LocalFileSystem/Extensions/DirectoryInfoExtensions.cs
Method: FindFiles
Current Implementation
internal static class DirectoryInfoExtensions
{
public static IEnumerable<FileInfo> FindFiles(this DirectoryInfo directoryInfo, IPluginLogger logger, ListParameters listParameters)
{
if (directoryInfo == null)
throw new ArgumentNullException(nameof(directoryInfo), Resources.TheDirectoryCouldNotBeNull);
if (!directoryInfo.Exists)
throw new DirectoryNotFoundException(string.Format(Resources.TheDirectoryDoesNotExist, directoryInfo.FullName));
var searchOption = listParameters.Recurse is true ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
var files = directoryInfo.EnumerateFiles("*", searchOption);
var result = new List<FileInfo>();
Regex? regex = null;
if (!string.IsNullOrEmpty(listParameters.Filter))
{
var regexOptions = listParameters.CaseSensitive is true ? RegexOptions.IgnoreCase : RegexOptions.None;
regex = new Regex(listParameters.Filter, regexOptions);
}
foreach (var file in files)
{
try
{
var resultCount = 0;
var isMatched = regex != null && regex.IsMatch(file.FullName);
if (listParameters.Filter != null && !isMatched)
continue;
result.Add(file);
resultCount++;
if (listParameters.MaxResults.HasValue && resultCount >= listParameters.MaxResults)
{
break;
}
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
return result;
}
}Suggested Refactoring Ideas
- Extract smaller helper methods:
ValidateDirectory(DirectoryInfo directoryInfo)CreateRegex(ListParameters listParameters)ShouldIncludeFile(FileInfo file, Regex? regex, ListParameters listParameters)
- Move
resultCountoutside the loop to avoid redundant initialization. - Simplify nested logic using early
continueor extracted conditions.
Proposed Implementation
internal static class DirectoryInfoExtensions
{
public static IEnumerable<FileInfo> FindFiles(this DirectoryInfo directoryInfo, IPluginLogger logger, ListParameters listParameters)
{
ValidateDirectory(directoryInfo);
var searchOption = listParameters.Recurse == true
? SearchOption.AllDirectories
: SearchOption.TopDirectoryOnly;
var regex = CreateRegex(listParameters);
var files = directoryInfo.EnumerateFiles("*", searchOption);
var result = new List<FileInfo>();
int resultCount = 0;
foreach (var file in files)
{
if (!ShouldIncludeFile(file, regex, listParameters))
continue;
try
{
result.Add(file);
resultCount++;
if (listParameters.MaxResults.HasValue && resultCount >= listParameters.MaxResults)
break;
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
return result;
}
private static void ValidateDirectory(DirectoryInfo directoryInfo)
{
if (directoryInfo == null)
throw new ArgumentNullException(nameof(directoryInfo), Resources.TheDirectoryCouldNotBeNull);
if (!directoryInfo.Exists)
throw new DirectoryNotFoundException(string.Format(Resources.TheDirectoryDoesNotExist, directoryInfo.FullName));
}
private static Regex? CreateRegex(ListParameters listParameters)
{
if (string.IsNullOrEmpty(listParameters.Filter))
return null;
var regexOptions = listParameters.CaseSensitive == true
? RegexOptions.None
: RegexOptions.IgnoreCase;
return new Regex(listParameters.Filter, regexOptions);
}
private static bool ShouldIncludeFile(FileInfo file, Regex? regex, ListParameters listParameters)
{
if (regex == null)
return true;
return regex.IsMatch(file.FullName);
}
}Acceptance Criteria
- Cognitive Complexity ≤ 15
- Code passes existing unit tests (no behavioral changes)
- Maintains:
- Exception handling
- Logging
- Filtering and recursion logic
MaxResultsfunctionality
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
C#C# related codeC# related codeenhancementNew feature or requestNew feature or requestgood first issueGood for newcomersGood for newcomershacktoberfest-acceptedhelp wantedExtra attention is neededExtra attention is neededrefactoringRefactoring codeRefactoring codereliability