// Copyright (c) Microsoft. All rights reserved. namespace VerifySamples; /// /// Parsed command-line options for the sample verification tool. /// internal sealed class VerifyOptions { /// /// Maximum number of samples to run concurrently. /// public int MaxParallelism { get; init; } = 8; /// /// Path to write a CSV summary file, or null to skip. /// public string? CsvFilePath { get; init; } /// /// Path to write a Markdown summary file, or null to skip. /// public string? MarkdownFilePath { get; init; } /// /// Path to write a sequential log file, or null to skip. /// public string? LogFilePath { get; init; } /// /// When true, samples are built as part of dotnet run. /// When false (the default), --no-build is passed, assuming a prior build step. /// public bool BuildSamples { get; init; } /// /// The filtered list of samples to process. /// public required IReadOnlyList Samples { get; init; } /// /// All known sample set registries, keyed by category name. /// private static readonly Dictionary> s_sampleSets = new(StringComparer.OrdinalIgnoreCase) { ["01-get-started"] = GetStartedSamples.All, ["02-agents"] = AgentsSamples.All, ["03-workflows"] = WorkflowSamples.All, }; /// /// Parses command-line arguments and resolves the sample list. /// Returns null and writes to stderr if the arguments are invalid. /// public static VerifyOptions? Parse(string[] args) { var argList = args.ToList(); var categoryFilter = ExtractArg(argList, "--category"); var logFilePath = ExtractArg(argList, "--log"); var csvFilePath = ExtractArg(argList, "--csv"); var markdownFilePath = ExtractArg(argList, "--md"); var buildSamples = ExtractFlag(argList, "--build"); int maxParallelism = 8; var parallelArg = ExtractArg(argList, "--parallel"); if (parallelArg is not null && int.TryParse(parallelArg, out var p) && p > 0) { maxParallelism = p; } HashSet? nameFilter = null; if (argList.Count > 0) { nameFilter = argList.ToHashSet(StringComparer.OrdinalIgnoreCase); } // Build the sample list IReadOnlyList samples; if (categoryFilter is not null) { if (!s_sampleSets.TryGetValue(categoryFilter, out var categoryList)) { Console.Error.WriteLine( $"Unknown category '{categoryFilter}'. Available: {string.Join(", ", s_sampleSets.Keys)}"); return null; } samples = categoryList; } else { samples = s_sampleSets.Values.SelectMany(s => s).ToList(); } if (nameFilter is not null) { samples = samples.Where(s => nameFilter.Contains(s.Name)).ToList(); } if (samples.Count == 0) { var allNames = s_sampleSets.Values.SelectMany(s => s).Select(s => s.Name); Console.Error.WriteLine($"No matching samples found. Available: {string.Join(", ", allNames)}"); return null; } return new VerifyOptions { MaxParallelism = maxParallelism, LogFilePath = logFilePath, CsvFilePath = csvFilePath, MarkdownFilePath = markdownFilePath, BuildSamples = buildSamples, Samples = samples, }; } private static string? ExtractArg(List list, string flag) { var idx = list.IndexOf(flag); if (idx < 0) { return null; } if (idx + 1 >= list.Count) { Console.Error.WriteLine($"Missing value for {flag}."); list.RemoveAt(idx); return null; } var value = list[idx + 1]; list.RemoveRange(idx, 2); return value; } private static bool ExtractFlag(List list, string flag) { var idx = list.IndexOf(flag); if (idx < 0) { return false; } list.RemoveAt(idx); return true; } }