From 9196cf3448638e7e58a14eefb2e011bde81db9a3 Mon Sep 17 00:00:00 2001 From: irongut Date: Sat, 19 Feb 2022 02:37:17 +0000 Subject: [PATCH 1/5] dont fail if branch metrics missing #33 --- src/CodeCoverageSummary/Program.cs | 31 +- src/coverage.simplecov.xml | 441 +++++++++++++++++++++++++++++ 2 files changed, 461 insertions(+), 11 deletions(-) create mode 100644 src/coverage.simplecov.xml diff --git a/src/CodeCoverageSummary/Program.cs b/src/CodeCoverageSummary/Program.cs index e1e2ca3..433e962 100644 --- a/src/CodeCoverageSummary/Program.cs +++ b/src/CodeCoverageSummary/Program.cs @@ -59,6 +59,11 @@ private static int Main(string[] args) } else { + // hide branch rate if metrics missing + bool hideBranchRate = o.HideBranchRate; + if (summary.BranchRate == 0 && summary.BranchesCovered == 0 && summary.BranchesValid == 0) + hideBranchRate = true; + // set health badge thresholds if (!string.IsNullOrWhiteSpace(o.Thresholds)) SetThresholds(o.Thresholds); @@ -72,14 +77,14 @@ private static int Main(string[] args) if (o.Format.Equals("text", StringComparison.OrdinalIgnoreCase)) { fileExt = "txt"; - output = GenerateTextOutput(summary, badgeUrl, o.Indicators, o.HideBranchRate, o.HideComplexity); + output = GenerateTextOutput(summary, badgeUrl, o.Indicators, hideBranchRate, o.HideComplexity); if (o.FailBelowThreshold) output += $"Minimum allowed line rate is {lowerThreshold * 100:N0}%{Environment.NewLine}"; } else if (o.Format.Equals("md", StringComparison.OrdinalIgnoreCase) || o.Format.Equals("markdown", StringComparison.OrdinalIgnoreCase)) { fileExt = "md"; - output = GenerateMarkdownOutput(summary, badgeUrl, o.Indicators, o.HideBranchRate, o.HideComplexity); + output = GenerateMarkdownOutput(summary, badgeUrl, o.Indicators, hideBranchRate, o.HideComplexity); if (o.FailBelowThreshold) output += $"{Environment.NewLine}_Minimum allowed line rate is `{lowerThreshold * 100:N0}%`_{Environment.NewLine}"; } @@ -156,17 +161,21 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary var branchR = from item in coverage.Attributes() where item.Name == "branch-rate" select item; - summary.BranchRate += double.Parse(branchR.First().Value); - var branchesCovered = from item in coverage.Attributes() - where item.Name == "branches-covered" - select item; - summary.BranchesCovered += int.Parse(branchesCovered.First().Value); + if (branchR.Any()) + { + summary.BranchRate += double.Parse(branchR.First().Value); + + var branchesCovered = from item in coverage.Attributes() + where item.Name == "branches-covered" + select item; + summary.BranchesCovered += int.Parse(branchesCovered.First().Value); - var branchesValid = from item in coverage.Attributes() - where item.Name == "branches-valid" - select item; - summary.BranchesValid += int.Parse(branchesValid.First().Value); + var branchesValid = from item in coverage.Attributes() + where item.Name == "branches-valid" + select item; + summary.BranchesValid += int.Parse(branchesValid.First().Value); + } // test coverage for individual packages var packages = from item in coverage.Descendants("package") diff --git a/src/coverage.simplecov.xml b/src/coverage.simplecov.xml new file mode 100644 index 0000000..b29e3fd --- /dev/null +++ b/src/coverage.simplecov.xml @@ -0,0 +1,441 @@ + + + + + + /Users/pboling/src/my/oauth2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 1c5e7f1a6096f7d6d3ba8f169d6a8b6702f73f25 Mon Sep 17 00:00:00 2001 From: irongut Date: Sat, 19 Feb 2022 03:25:34 +0000 Subject: [PATCH 2/5] improved error handling when parsing coverage files #33 --- src/CodeCoverageSummary/Program.cs | 38 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/CodeCoverageSummary/Program.cs b/src/CodeCoverageSummary/Program.cs index 433e962..71db0bd 100644 --- a/src/CodeCoverageSummary/Program.cs +++ b/src/CodeCoverageSummary/Program.cs @@ -49,12 +49,16 @@ private static int Main(string[] args) Console.WriteLine($"Code Coverage File: {file}"); summary = ParseTestResults(file, summary); } + + if (summary == null) + return -2; // error + summary.LineRate /= matchingFiles.Count(); summary.BranchRate /= matchingFiles.Count(); if (summary.Packages.Count == 0) { - Console.WriteLine("Error: Parsing code coverage file, no packages found."); + Console.WriteLine("Parsing Error: No packages found in coverage files."); return -2; // error } else @@ -97,6 +101,7 @@ private static int Main(string[] args) // output if (o.Output.Equals("console", StringComparison.OrdinalIgnoreCase)) { + Console.WriteLine(); Console.WriteLine(output); } else if (o.Output.Equals("file", StringComparison.OrdinalIgnoreCase)) @@ -105,6 +110,7 @@ private static int Main(string[] args) } else if (o.Output.Equals("both", StringComparison.OrdinalIgnoreCase)) { + Console.WriteLine(); Console.WriteLine(output); File.WriteAllText($"code-coverage-results.{fileExt}", output); } @@ -134,6 +140,9 @@ private static int Main(string[] args) private static CodeSummary ParseTestResults(string filename, CodeSummary summary) { + if (summary == null) + return null; + try { string rss = File.ReadAllText(filename); @@ -143,19 +152,34 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary var coverage = from item in xdoc.Descendants("coverage") select item; + if (!coverage.Any()) + throw new Exception("Coverage file invalid, data not found"); + var lineR = from item in coverage.Attributes() where item.Name == "line-rate" select item; + + if (!lineR.Any()) + throw new Exception("Summary Line Rate not found"); + summary.LineRate += double.Parse(lineR.First().Value); var linesCovered = from item in coverage.Attributes() where item.Name == "lines-covered" select item; + + if (!linesCovered.Any()) + throw new Exception("Summary Lines Covered not found"); + summary.LinesCovered += int.Parse(linesCovered.First().Value); var linesValid = from item in coverage.Attributes() where item.Name == "lines-valid" select item; + + if (!linesValid.Any()) + throw new Exception("Summary Lines Valid not found"); + summary.LinesValid += int.Parse(linesValid.First().Value); var branchR = from item in coverage.Attributes() @@ -169,12 +193,16 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary var branchesCovered = from item in coverage.Attributes() where item.Name == "branches-covered" select item; - summary.BranchesCovered += int.Parse(branchesCovered.First().Value); + + if (branchesCovered.Any()) + summary.BranchesCovered += int.Parse(branchesCovered.First().Value); var branchesValid = from item in coverage.Attributes() where item.Name == "branches-valid" select item; - summary.BranchesValid += int.Parse(branchesValid.First().Value); + + if (branchesValid.Any()) + summary.BranchesValid += int.Parse(branchesValid.First().Value); } // test coverage for individual packages @@ -186,7 +214,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary { CodeCoverage packageCoverage = new() { - Name = string.IsNullOrWhiteSpace(item.Attribute("name").Value) ? $"Package {i}" : item.Attribute("name").Value, + Name = string.IsNullOrWhiteSpace(item.Attribute("name")?.Value) ? $"Package {i}" : item.Attribute("name").Value, LineRate = double.Parse(item.Attribute("line-rate")?.Value ?? "0"), BranchRate = double.Parse(item.Attribute("branch-rate")?.Value ?? "0"), Complexity = double.Parse(item.Attribute("complexity")?.Value ?? "0") @@ -200,7 +228,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary } catch (Exception ex) { - Console.WriteLine($"Parse Error: {ex.Message}"); + Console.WriteLine($"Parsing Error: {ex.Message} - {filename}"); return null; } } From 4c876916c916191e3d0df620c20880e311758a31 Mon Sep 17 00:00:00 2001 From: irongut Date: Sat, 19 Feb 2022 03:28:59 +0000 Subject: [PATCH 3/5] use AsSpan instead of SubString --- src/CodeCoverageSummary/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CodeCoverageSummary/Program.cs b/src/CodeCoverageSummary/Program.cs index 71db0bd..4510201 100644 --- a/src/CodeCoverageSummary/Program.cs +++ b/src/CodeCoverageSummary/Program.cs @@ -249,10 +249,10 @@ private static void SetThresholds(string thresholds) } else { - if (!int.TryParse(thresholds.Substring(0, s), out lowerPercentage)) + if (!int.TryParse(thresholds.AsSpan(0, s), out lowerPercentage)) throw new ArgumentException("Threshold parameter set incorrectly."); - if (!int.TryParse(thresholds.Substring(s + 1), out upperPercentage)) + if (!int.TryParse(thresholds.AsSpan(s + 1), out upperPercentage)) throw new ArgumentException("Threshold parameter set incorrectly."); } lowerThreshold = lowerPercentage / 100.0; From 1699cd4b65cca5a627a440408ba9d08bad26ffa9 Mon Sep 17 00:00:00 2001 From: irongut Date: Sat, 19 Feb 2022 18:02:02 +0000 Subject: [PATCH 4/5] improved error messages #33 --- src/CodeCoverageSummary/Program.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/CodeCoverageSummary/Program.cs b/src/CodeCoverageSummary/Program.cs index 4510201..3e33c78 100644 --- a/src/CodeCoverageSummary/Program.cs +++ b/src/CodeCoverageSummary/Program.cs @@ -37,7 +37,7 @@ private static int Main(string[] args) { if (!File.Exists(file)) { - Console.WriteLine($"Error: Code coverage file not found - {file}."); + Console.WriteLine($"Error: Coverage file not found - {file}."); return -2; // error } } @@ -46,7 +46,7 @@ private static int Main(string[] args) CodeSummary summary = new(); foreach (var file in matchingFiles) { - Console.WriteLine($"Code Coverage File: {file}"); + Console.WriteLine($"Coverage File: {file}"); summary = ParseTestResults(file, summary); } @@ -160,7 +160,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary select item; if (!lineR.Any()) - throw new Exception("Summary Line Rate not found"); + throw new Exception("Overall line rate not found"); summary.LineRate += double.Parse(lineR.First().Value); @@ -169,7 +169,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary select item; if (!linesCovered.Any()) - throw new Exception("Summary Lines Covered not found"); + throw new Exception("Overall lines covered not found"); summary.LinesCovered += int.Parse(linesCovered.First().Value); @@ -178,7 +178,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary select item; if (!linesValid.Any()) - throw new Exception("Summary Lines Valid not found"); + throw new Exception("Overall lines valid not found"); summary.LinesValid += int.Parse(linesValid.First().Value); @@ -209,6 +209,9 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary var packages = from item in coverage.Descendants("package") select item; + if (!packages.Any()) + throw new Exception("No package data found"); + int i = 1; foreach (var item in packages) { From 7b1923cbc6764d478dc798045bc04b881136bfd8 Mon Sep 17 00:00:00 2001 From: irongut Date: Sat, 19 Feb 2022 18:10:29 +0000 Subject: [PATCH 5/5] improved generated package names when names missing --- src/CodeCoverageSummary/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CodeCoverageSummary/Program.cs b/src/CodeCoverageSummary/Program.cs index 3e33c78..9f56f18 100644 --- a/src/CodeCoverageSummary/Program.cs +++ b/src/CodeCoverageSummary/Program.cs @@ -217,7 +217,7 @@ private static CodeSummary ParseTestResults(string filename, CodeSummary summary { CodeCoverage packageCoverage = new() { - Name = string.IsNullOrWhiteSpace(item.Attribute("name")?.Value) ? $"Package {i}" : item.Attribute("name").Value, + Name = string.IsNullOrWhiteSpace(item.Attribute("name")?.Value) ? $"{Path.GetFileNameWithoutExtension(filename)} Package {i}" : item.Attribute("name").Value, LineRate = double.Parse(item.Attribute("line-rate")?.Value ?? "0"), BranchRate = double.Parse(item.Attribute("branch-rate")?.Value ?? "0"), Complexity = double.Parse(item.Attribute("complexity")?.Value ?? "0")