using System.Text; namespace AyCode.Core.Benchmarks.Reporting; /// /// Context bundle for the unified benchmark report writer. Same record on both sides (Console / BDN), /// only the differs ("Console" / "Bdn") — that drives the filename prefix /// (e.g. Console.FullBenchmark_Release_{timestamp}.LLM vs Bdn.FullBenchmark_Release_{timestamp}.LLM). /// The resolution walks up from to the /// nearest AyCode.Core.sln and combines with Test_Benchmark_Results\Benchmark — works across /// build modes (Debug / Release / AOT publish) and worktrees (each worktree has its own .sln, so its bench /// results land alongside its code). /// public sealed record ReportingContext( string SourceTag, string ResultsDirectory, string BuildConfiguration, UTF8Encoding Utf8NoBom) { /// /// Resolves the canonical by walking up from /// to the nearest AyCode.Core.sln, then combining /// with Test_Benchmark_Results\Benchmark. The build configuration is supplied by the caller /// (Console resolves via #if AYCODE_NATIVEAOT|DEBUG|else Release; BDN-side currently mirrors /// the JIT vs AOT discriminator from ). /// public static ReportingContext Create(string sourceTag, string buildConfiguration) => new(sourceTag, ResolveResultsDirectory(), buildConfiguration, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); /// /// Walk-up from the assembly's BaseDirectory to find the repo root (marker: AyCode.Core.sln). /// Returns {repoRoot}\Test_Benchmark_Results\Benchmark. Worktree-aware: if running from a /// worktree, the walk finds the worktree's own .sln (each worktree has its own checkout), so /// results land in the worktree's results folder — the natural place when the worktree's code /// changes are what produced the numbers. /// private static string ResolveResultsDirectory() { var dir = new DirectoryInfo(AppContext.BaseDirectory); while (dir != null && !File.Exists(Path.Combine(dir.FullName, "AyCode.Core.sln"))) dir = dir.Parent; if (dir == null) throw new InvalidOperationException( "Cannot locate repo root (AyCode.Core.sln) from AppContext.BaseDirectory: " + AppContext.BaseDirectory); return Path.Combine(dir.FullName, "Test_Benchmark_Results", "Benchmark"); } }