| | | 1 | | namespace AspxLint.Core; |
| | | 2 | | |
| | 83 | 3 | | public sealed record ScannedFile( |
| | 83 | 4 | | string AbsolutePath, |
| | 83 | 5 | | string RelativePath, |
| | 83 | 6 | | int LineCount, |
| | 83 | 7 | | string Content, |
| | 83 | 8 | | IReadOnlyList<Issue> Issues |
| | 83 | 9 | | ); |
| | | 10 | | |
| | | 11 | | public static class ProjectScanner |
| | | 12 | | { |
| | | 13 | | public static readonly string[] DefaultExtensions = { ".aspx", ".ascx", ".master", ".asax" }; |
| | | 14 | | |
| | | 15 | | public static IEnumerable<ScannedFile> Scan( |
| | | 16 | | string root, |
| | | 17 | | IEnumerable<IRule> rules, |
| | | 18 | | IEnumerable<string>? extensions = null) |
| | | 19 | | { |
| | | 20 | | if (!Directory.Exists(root)) |
| | | 21 | | throw new DirectoryNotFoundException($"Dossier introuvable : {root}"); |
| | | 22 | | |
| | | 23 | | var exts = (extensions ?? DefaultExtensions) |
| | | 24 | | .Select(e => e.ToLowerInvariant()) |
| | | 25 | | .ToHashSet(); |
| | | 26 | | var rulesList = rules.ToList(); |
| | | 27 | | |
| | | 28 | | foreach (var path in Directory.EnumerateFiles(root, "*.*", SearchOption.AllDirectories)) |
| | | 29 | | { |
| | | 30 | | var ext = Path.GetExtension(path).ToLowerInvariant(); |
| | | 31 | | if (!exts.Contains(ext)) continue; |
| | | 32 | | |
| | | 33 | | string content; |
| | | 34 | | try |
| | | 35 | | { |
| | | 36 | | // Lecture BOM-aware : on conserve le BOM dans la chaine sous forme de |
| | | 37 | | // caractere , ce qui permet a WS-005 de le detecter et a /api/save |
| | | 38 | | // de le re-emettre fidelement (UTF-8 encode en EF BB BF). |
| | | 39 | | var bytes = File.ReadAllBytes(path); |
| | | 40 | | var hasBom = bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF; |
| | | 41 | | content = hasBom |
| | | 42 | | ? "" + System.Text.Encoding.UTF8.GetString(bytes, 3, bytes.Length - 3) |
| | | 43 | | : System.Text.Encoding.UTF8.GetString(bytes); |
| | | 44 | | } |
| | | 45 | | catch { continue; } |
| | | 46 | | |
| | | 47 | | var issues = Analyzer.Analyze(path, content, rulesList); |
| | | 48 | | var lineCount = 1; |
| | | 49 | | foreach (var c in content) if (c == '\n') lineCount++; |
| | | 50 | | var rel = Path.GetRelativePath(root, path); |
| | | 51 | | |
| | | 52 | | yield return new ScannedFile(path, rel, lineCount, content, issues); |
| | | 53 | | } |
| | | 54 | | } |
| | | 55 | | } |