private static string GenerateBadge(CodeSummary summary) { string colour; if (summary.LineRate < 0.5) { colour = "critical"; } else if (summary.LineRate < 0.75) { colour = "yellow"; } else { colour = "success"; } return($"https://img.shields.io/badge/Code%20Coverage-{summary.LineRate * 100:N0}%25-{colour}?style=flat"); }
private static string GenerateTextOutput(CodeSummary summary, string badgeUrl) { StringBuilder textOutput = new(); if (!string.IsNullOrWhiteSpace(badgeUrl)) { textOutput.AppendLine(badgeUrl); } textOutput.AppendLine($"Line Rate = {summary.LineRate * 100:N0}%, Lines Covered = {summary.LinesCovered} / {summary.LinesValid}") .AppendLine($"Branch Rate = {summary.BranchRate * 100:N0}%, Branches Covered = {summary.BranchesCovered} / {summary.BranchesValid}") .AppendLine($"Complexity = {summary.Complexity}"); foreach (CodeCoverage package in summary.Packages) { textOutput.AppendLine($"{package.Name}: Line Rate = {package.LineRate * 100:N0}%, Branch Rate = {package.BranchRate * 100:N0}%, Complexity = {package.Complexity}"); } return(textOutput.ToString()); }
private static string GenerateMarkdownOutput(CodeSummary summary, string badgeUrl) { StringBuilder markdownOutput = new(); if (!string.IsNullOrWhiteSpace(badgeUrl)) { markdownOutput.AppendLine($"![Code Coverage]({badgeUrl})"); } markdownOutput.AppendLine("Package | Line Rate | Branch Rate | Complexity") .AppendLine("-------- | --------- | ----------- | ----------"); foreach (CodeCoverage package in summary.Packages) { markdownOutput.AppendLine($"{package.Name} | {package.LineRate * 100:N0}% | {package.BranchRate * 100:N0}% | {package.Complexity}"); } markdownOutput.Append($"**Summary** | **{summary.LineRate * 100:N0}%** ({summary.LinesCovered} / {summary.LinesValid}) | ") .AppendLine($"**{summary.BranchRate * 100:N0}%** ({summary.BranchesCovered} / {summary.BranchesValid}) | {summary.Complexity}"); return(markdownOutput.ToString()); }
// test file: /Dev/Csharp/CodeCoverageSummary/coverage.cobertura.xml private static int Main(string[] args) { return(Parser.Default.ParseArguments <CommandLineOptions>(args) .MapResult(o => { try { if (!File.Exists(o.Filename)) { Console.WriteLine("Error: Code coverage file not found."); return -2; // error } // parse code coverage file Console.WriteLine($"Code Coverage File: {o.Filename}"); CodeSummary summary = ParseTestResults(o.Filename); if (summary == null) { Console.WriteLine("Error: Parsing code coverage file."); return -2; // error } else { // generate badge string badgeUrl = o.Badge ? GenerateBadge(summary) : null; // generate output string output; string fileExt; if (o.Format.Equals("text", StringComparison.OrdinalIgnoreCase)) { fileExt = "txt"; output = GenerateTextOutput(summary, badgeUrl); } else if (o.Format.Equals("md", StringComparison.OrdinalIgnoreCase) || o.Format.Equals("markdown", StringComparison.OrdinalIgnoreCase)) { fileExt = "md"; output = GenerateMarkdownOutput(summary, badgeUrl); } else { Console.WriteLine("Error: Unknown output format."); return -2; // error } // output if (o.Output.Equals("console", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine(output); } else if (o.Output.Equals("file", StringComparison.OrdinalIgnoreCase)) { File.WriteAllText($"code-coverage-results.{fileExt}", output); } else if (o.Output.Equals("both", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine(output); File.WriteAllText($"code-coverage-results.{fileExt}", output); } else { Console.WriteLine("Error: Unknown output type."); return -2; // error } return 0; // success } } catch (Exception ex) { Console.WriteLine($"Error: {ex.GetType()} - {ex.Message}"); return -3; // unhandled error } }, errs => - 1)); // invalid arguments }