diff --git a/reports/current.md b/reports/current.md index 0dddfe2..66a8126 100644 --- a/reports/current.md +++ b/reports/current.md @@ -1,6 +1,6 @@ # NATS .NET Porting Status Report -Generated: 2026-02-27 10:34:31 UTC +Generated: 2026-02-27 10:35:52 UTC ## Modules (12 total) diff --git a/reports/report_485c7b0.md b/reports/report_485c7b0.md new file mode 100644 index 0000000..66a8126 --- /dev/null +++ b/reports/report_485c7b0.md @@ -0,0 +1,37 @@ +# NATS .NET Porting Status Report + +Generated: 2026-02-27 10:35:52 UTC + +## Modules (12 total) + +| Status | Count | +|--------|-------| +| verified | 12 | + +## Features (3673 total) + +| Status | Count | +|--------|-------| +| deferred | 2500 | +| n_a | 18 | +| stub | 168 | +| verified | 987 | + +## Unit Tests (3257 total) + +| Status | Count | +|--------|-------| +| deferred | 2680 | +| n_a | 187 | +| verified | 390 | + +## Library Mappings (36 total) + +| Status | Count | +|--------|-------| +| mapped | 36 | + + +## Overall Progress + +**1594/6942 items complete (23.0%)** diff --git a/tools/NatsNet.PortTracker/Commands/AuditCommand.cs b/tools/NatsNet.PortTracker/Commands/AuditCommand.cs index 494520d..8153683 100644 --- a/tools/NatsNet.PortTracker/Commands/AuditCommand.cs +++ b/tools/NatsNet.PortTracker/Commands/AuditCommand.cs @@ -7,18 +7,28 @@ namespace NatsNet.PortTracker.Commands; public static class AuditCommand { + private record AuditTarget(string Table, string Label, string DefaultSource, string DefaultOutput); + + private static readonly AuditTarget FeaturesTarget = new( + "features", "features", + Path.Combine(Directory.GetCurrentDirectory(), "dotnet", "src", "ZB.MOM.NatsNet.Server"), + Path.Combine(Directory.GetCurrentDirectory(), "reports", "audit-results.csv")); + + private static readonly AuditTarget TestsTarget = new( + "unit_tests", "unit tests", + Path.Combine(Directory.GetCurrentDirectory(), "dotnet", "tests", "ZB.MOM.NatsNet.Server.Tests"), + Path.Combine(Directory.GetCurrentDirectory(), "reports", "audit-results-tests.csv")); + public static Command Create(Option dbOption) { - var sourceOpt = new Option("--source") + var sourceOpt = new Option("--source") { - Description = "Path to the .NET source directory", - DefaultValueFactory = _ => Path.Combine(Directory.GetCurrentDirectory(), "dotnet", "src", "ZB.MOM.NatsNet.Server") + Description = "Path to the .NET source directory (defaults based on --type)" }; - var outputOpt = new Option("--output") + var outputOpt = new Option("--output") { - Description = "CSV report output path", - DefaultValueFactory = _ => Path.Combine(Directory.GetCurrentDirectory(), "reports", "audit-results.csv") + Description = "CSV report output path (defaults based on --type)" }; var moduleOpt = new Option("--module") @@ -32,44 +42,62 @@ public static class AuditCommand DefaultValueFactory = _ => false }; - var cmd = new Command("audit", "Classify unknown features by inspecting .NET source code"); + var typeOpt = new Option("--type") + { + Description = "What to audit: features, tests, or all", + DefaultValueFactory = _ => "features" + }; + + var cmd = new Command("audit", "Classify unknown features/tests by inspecting .NET source code"); cmd.Add(sourceOpt); cmd.Add(outputOpt); cmd.Add(moduleOpt); cmd.Add(executeOpt); + cmd.Add(typeOpt); cmd.SetAction(parseResult => { var dbPath = parseResult.GetValue(dbOption)!; - var sourcePath = parseResult.GetValue(sourceOpt)!; - var outputPath = parseResult.GetValue(outputOpt)!; + var sourceOverride = parseResult.GetValue(sourceOpt); + var outputOverride = parseResult.GetValue(outputOpt); var moduleId = parseResult.GetValue(moduleOpt); var execute = parseResult.GetValue(executeOpt); + var type = parseResult.GetValue(typeOpt)!; - RunAudit(dbPath, sourcePath, outputPath, moduleId, execute); + AuditTarget[] targets = type switch + { + "features" => [FeaturesTarget], + "tests" => [TestsTarget], + "all" => [FeaturesTarget, TestsTarget], + _ => throw new ArgumentException($"Unknown audit type: {type}. Use features, tests, or all.") + }; + + foreach (var target in targets) + { + var sourcePath = sourceOverride ?? target.DefaultSource; + var outputPath = outputOverride ?? target.DefaultOutput; + RunAudit(dbPath, sourcePath, outputPath, moduleId, execute, target); + } }); return cmd; } - private static void RunAudit(string dbPath, string sourcePath, string outputPath, int? moduleId, bool execute) + private static void RunAudit(string dbPath, string sourcePath, string outputPath, int? moduleId, bool execute, AuditTarget target) { - // Validate source directory if (!Directory.Exists(sourcePath)) { Console.WriteLine($"Error: source directory not found: {sourcePath}"); return; } - // 1. Build source index Console.WriteLine($"Parsing .NET source files in {sourcePath}..."); var indexer = new SourceIndexer(); indexer.IndexDirectory(sourcePath); Console.WriteLine($"Indexed {indexer.FilesIndexed} files, {indexer.MethodsIndexed} methods/properties."); - // 2. Query unknown features using var db = new Database(dbPath); - var sql = "SELECT id, dotnet_class, dotnet_method, go_file, go_method FROM features WHERE status = 'unknown'"; + var sql = $"SELECT id, dotnet_class, dotnet_method, go_file, go_method FROM {target.Table} WHERE status = 'unknown'"; var parameters = new List<(string, object?)>(); if (moduleId is not null) { @@ -81,12 +109,11 @@ public static class AuditCommand var rows = db.Query(sql, parameters.ToArray()); if (rows.Count == 0) { - Console.WriteLine("No unknown features found."); + Console.WriteLine($"No unknown {target.Label} found."); return; } - Console.WriteLine($"Found {rows.Count} unknown features to classify.\n"); + Console.WriteLine($"Found {rows.Count} unknown {target.Label} to classify.\n"); - // 3. Classify each feature var classifier = new FeatureClassifier(indexer); var results = new List<(FeatureClassifier.FeatureRecord Feature, FeatureClassifier.ClassificationResult Result)>(); @@ -103,17 +130,16 @@ public static class AuditCommand results.Add((feature, result)); } - // 4. Write CSV report WriteCsvReport(outputPath, results); - // 5. Print console summary var grouped = results.GroupBy(r => r.Result.Status) .ToDictionary(g => g.Key, g => g.Count()); - Console.WriteLine("Feature Status Audit Results"); - Console.WriteLine("============================="); + var label = char.ToUpper(target.Label[0]) + target.Label[1..]; + Console.WriteLine($"{label} Status Audit Results"); + Console.WriteLine(new string('=', $"{label} Status Audit Results".Length)); Console.WriteLine($"Source: {sourcePath} ({indexer.FilesIndexed} files, {indexer.MethodsIndexed} methods indexed)"); - Console.WriteLine($"Features audited: {results.Count}"); + Console.WriteLine($"{label} audited: {results.Count}"); Console.WriteLine(); Console.WriteLine($" verified: {grouped.GetValueOrDefault("verified", 0)}"); Console.WriteLine($" stub: {grouped.GetValueOrDefault("stub", 0)}"); @@ -128,8 +154,7 @@ public static class AuditCommand return; } - // 6. Apply DB updates - ApplyUpdates(db, results); + ApplyUpdates(db, results, target); Console.WriteLine($"Report: {outputPath}"); } @@ -137,7 +162,6 @@ public static class AuditCommand string outputPath, List<(FeatureClassifier.FeatureRecord Feature, FeatureClassifier.ClassificationResult Result)> results) { - // Ensure directory exists var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir); @@ -153,9 +177,9 @@ public static class AuditCommand private static void ApplyUpdates( Database db, - List<(FeatureClassifier.FeatureRecord Feature, FeatureClassifier.ClassificationResult Result)> results) + List<(FeatureClassifier.FeatureRecord Feature, FeatureClassifier.ClassificationResult Result)> results, + AuditTarget target) { - // Group by (status, notes) for efficient batch updates var groups = results .GroupBy(r => (r.Result.Status, Notes: r.Result.Status == "n_a" ? r.Result.Reason : (string?)null)) .ToList(); @@ -170,7 +194,6 @@ public static class AuditCommand var status = group.Key.Status; var notes = group.Key.Notes; - // Build parameterized IN clause var placeholders = new List(); using var cmd = db.CreateCommand(""); for (var i = 0; i < ids.Count; i++) @@ -183,12 +206,12 @@ public static class AuditCommand if (notes is not null) { - cmd.CommandText = $"UPDATE features SET status = @status, notes = @notes WHERE id IN ({string.Join(", ", placeholders)})"; + cmd.CommandText = $"UPDATE {target.Table} SET status = @status, notes = @notes WHERE id IN ({string.Join(", ", placeholders)})"; cmd.Parameters.AddWithValue("@notes", notes); } else { - cmd.CommandText = $"UPDATE features SET status = @status WHERE id IN ({string.Join(", ", placeholders)})"; + cmd.CommandText = $"UPDATE {target.Table} SET status = @status WHERE id IN ({string.Join(", ", placeholders)})"; } cmd.Transaction = transaction; @@ -197,7 +220,7 @@ public static class AuditCommand } transaction.Commit(); - Console.WriteLine($"Updated {totalUpdated} features."); + Console.WriteLine($"Updated {totalUpdated} {target.Label}."); } catch {