Skip to content

Commit 0ddc1c9

Browse files
committed
Improve file and directory filtering and error handling
Added 'venv' to ignored directories and improved file filtering to skip symbolic links and junction points. Enhanced ProjectScanner to handle inaccessible files and directories gracefully, and implemented manual recursive file enumeration to better respect filter rules and avoid I/O errors.
1 parent 9e163fb commit 0ddc1c9

4 files changed

Lines changed: 97 additions & 7 deletions

File tree

Configuration/FilterConfiguration.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public class FilterConfiguration
116116
{
117117
".sonarqube",
118118

119+
"venv",
120+
119121
// Version control systems
120122
".git", ".svn", ".hg", ".bzr", ".cvs",
121123

Services/ConfigLoader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Text.Json;
22
using CodeContext.Configuration;
3+
using CodeContext.Interfaces;
34

45
namespace CodeContext.Services;
56

Services/FileFilterService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ public bool ShouldSkip(FileSystemInfo info, string rootPath)
2424
Guard.NotNull(info, nameof(info));
2525
Guard.NotNullOrEmpty(rootPath, nameof(rootPath));
2626

27+
// Skip symbolic links and junction points to avoid I/O errors
28+
if (info.Attributes.HasFlag(FileAttributes.ReparsePoint))
29+
{
30+
return true;
31+
}
32+
2733
// Check if any parent directory is in the ignored list
2834
var relativePath = Path.GetRelativePath(rootPath, info.FullName);
2935
var pathParts = relativePath.Split(Path.DirectorySeparatorChar);

Services/ProjectScanner.cs

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,37 @@ public string GetProjectStructure(string projectPath, int indent = 0)
4747
}
4848

4949
var rootPath = _gitRepoRoot ?? projectPath;
50-
var entries = Directory.EnumerateFileSystemEntries(projectPath)
51-
.OrderBy(e => e)
52-
.Where(e => !_fileChecker.ShouldSkip(new FileInfo(e), rootPath))
53-
.ToList();
50+
51+
List<string> entries;
52+
try
53+
{
54+
var enumerationOptions = new EnumerationOptions
55+
{
56+
IgnoreInaccessible = true,
57+
RecurseSubdirectories = false
58+
};
59+
60+
entries = Directory.EnumerateFileSystemEntries(projectPath, "*", enumerationOptions)
61+
.OrderBy(e => e)
62+
.Where(e =>
63+
{
64+
try
65+
{
66+
return !_fileChecker.ShouldSkip(new FileInfo(e), rootPath);
67+
}
68+
catch
69+
{
70+
// Skip entries that can't be accessed
71+
return false;
72+
}
73+
})
74+
.ToList();
75+
}
76+
catch (Exception ex)
77+
{
78+
_console.WriteLine($"\n⚠️ Warning: Could not enumerate directory {projectPath}: {ex.Message}");
79+
return string.Empty;
80+
}
5481

5582
var structure = new StringBuilder();
5683

@@ -87,9 +114,10 @@ public string GetFileContents(string projectPath)
87114
_console.WriteLine("\n📄 Processing files...");
88115

89116
var rootPath = _gitRepoRoot ?? projectPath;
90-
var files = Directory.EnumerateFiles(projectPath, "*", SearchOption.AllDirectories)
91-
.Where(f => !_fileChecker.ShouldSkip(new FileInfo(f), rootPath))
92-
.ToList();
117+
var files = new List<string>();
118+
119+
// Manually enumerate files recursively to respect filters
120+
EnumerateFilesRecursively(projectPath, rootPath, files);
93121

94122
var fileContents = new List<string>();
95123
for (int i = 0; i < files.Count; i++)
@@ -111,6 +139,59 @@ public string GetFileContents(string projectPath)
111139
return string.Join("\n\n", fileContents);
112140
}
113141

142+
/// <summary>
143+
/// Recursively enumerates files while respecting filter rules.
144+
/// </summary>
145+
private void EnumerateFilesRecursively(string directory, string rootPath, List<string> files)
146+
{
147+
try
148+
{
149+
var enumerationOptions = new EnumerationOptions
150+
{
151+
IgnoreInaccessible = true,
152+
RecurseSubdirectories = false
153+
};
154+
155+
// Get files in current directory
156+
foreach (var file in Directory.EnumerateFiles(directory, "*", enumerationOptions))
157+
{
158+
try
159+
{
160+
var fileInfo = new FileInfo(file);
161+
if (!_fileChecker.ShouldSkip(fileInfo, rootPath))
162+
{
163+
files.Add(file);
164+
}
165+
}
166+
catch
167+
{
168+
// Skip files that can't be accessed
169+
}
170+
}
171+
172+
// Recursively process subdirectories
173+
foreach (var subDir in Directory.EnumerateDirectories(directory, "*", enumerationOptions))
174+
{
175+
try
176+
{
177+
var dirInfo = new DirectoryInfo(subDir);
178+
if (!_fileChecker.ShouldSkip(dirInfo, rootPath))
179+
{
180+
EnumerateFilesRecursively(subDir, rootPath, files);
181+
}
182+
}
183+
catch
184+
{
185+
// Skip directories that can't be accessed
186+
}
187+
}
188+
}
189+
catch (Exception ex)
190+
{
191+
_console.WriteLine($"\n⚠️ Warning: Could not enumerate directory {directory}: {ex.Message}");
192+
}
193+
}
194+
114195
/// <summary>
115196
/// Gets the root path of the git repository containing the scanned path.
116197
/// </summary>

0 commit comments

Comments
 (0)