From aa1d224b09fa66f4bd134711cf8c07aab9ef57ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 19 Feb 2024 18:10:25 +0100 Subject: [PATCH 1/9] remove current versions in release plan (#1623) --- Documentation/ReleasePlan.md | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/Documentation/ReleasePlan.md b/Documentation/ReleasePlan.md index 742b7d34b..22ff83dcd 100644 --- a/Documentation/ReleasePlan.md +++ b/Documentation/ReleasePlan.md @@ -19,38 +19,6 @@ We release 3 components as NuGet packages: **coverlet.console.nupkg** **coverlet.collector.nupkg** -### Current versions - -| Package | Version | -|:----------------------|:--------| -|**coverlet.msbuild** | 6.0.0 | -|**coverlet.console** | 6.0.0 | -|**coverlet.collector** | 6.0.0 | - -| Release Date | coverlet.msbuild | coverlet.console | coverlet.collector| commit hash | notes | -| :-----------------|:-----------------|:------------------|:------------------|:-----------------------------------------|:-------------------------------| -| 05 May 2023 | 6.0.0 | 6.0.0 | 6.0.0 | 3ad4fa1d5cd7ffe206c0cb9dc805ee6ca5a7b550 | Version aligned with github one| -| 29 Oct 2022 | 3.2.0 | 3.2.0 | 3.2.0 | e2c9d84a84a9d2d240ac15feb70f9198c6f8e173 | | -| 06 Feb 2022 | 3.1.2 | 3.1.2 | 3.1.2 | e335b1a8025e49e2f2de6b40ef12ec9d3ed11ceb | Fix CoreLib coverage issues | -| 30 Jan 2022 | 3.1.1 | 3.1.1 | 3.1.1 | e4278c06faba63122a870df15a1a1b934f6bc81d | | -| 19 July 2021 | 3.1.0 | 3.1.0 | 3.1.0 | 5a0ecc1e92fd754e2439dc3e4c828ff7386aa1a7 | Support for determistic build | -| 21 February 2021 | 3.0.3 | 3.0.3 | 3.0.3 | adfabfd58de0aabe263e7d2080324e0b8541071e | Fix regressions | -| 24 January 2021 | 3.0.2 | 3.0.2 | 3.0.2 | ed918515492193fd154b60270d440c40fa30fee9 | Fix regressions | -| 16 January 2021 | 3.0.1 | 3.0.1 | 3.0.1 | 1b45fd89245369ae94407e7a77bdfee112042486 | Fix severe coverage regression | -| 09 January 2021 | 3.0.0 | 3.0.0 | 3.0.0 | 1e77f9d2183a320e8991bfc296460e793301931f | Align versions numbers | -| 30 May 2020 | 2.9.0 | 1.7.2 | 1.3.0 | 83a38d45b3f9c231d705bfed849efbf41b3aaa86 | deterministic build support | -| 04 April 2020 | 2.8.1 | 1.7.1 | 1.2.1 | 3f81828821d07d756e02a4105b2533cedf0b543c | | -| 03 January 2019 | 2.8.0 | 1.7.0 | 1.2.0 | 72a688f1c47fa92059540d5fbb1c4b0b4bf0dc8c | | -| 23 September 2019 | 2.7.0 | 1.6.0 | 1.1.0 | 4ca01eb239038808739699470a61fad675af6c79 | | -| 01 July 2019 | 2.6.3 | 1.5.3 | 1.0.1 | e1593359497fdfe6befbb86304b8f4e09a656d14 | | -| 06 June 2019 | 2.6.2 | 1.5.2 | 1.0.0 | 3e7eac9df094c22335711a298d359890aed582e8 | first collector release | - -To get the list of commits between two version use git command - -```bash -git log --oneline hashbefore currenthash -``` - ## How to manually compare latest release with nightly build Before creating a new release it makes sense to test the new release against a benchmark repository. This can help to determine bugs that haven't been found From 59430c38879a5780ee296e686901e78f33ea17e6 Mon Sep 17 00:00:00 2001 From: Bert Date: Sat, 24 Feb 2024 21:06:49 +0100 Subject: [PATCH 2/9] Fix issues for V6.0.1 nuget packages (collector, console) (#1628) --- Directory.Packages.props | 2 +- src/coverlet.console/Program.cs | 14 +++++++------- src/coverlet.core/CoverageResult.cs | 2 +- src/coverlet.core/coverlet.core.csproj | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 015e0ee98..580a1c491 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -44,7 +44,7 @@ - + diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index 7bf4dad77..8782747a9 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -32,21 +32,21 @@ static int Main(string[] args) var targs = new Option(new[] { "--targetargs", "-a" }, "Arguments to be passed to the test runner.") { Arity = ArgumentArity.ZeroOrOne }; var output = new Option(new[] { "--output", "-o" }, "Output of the generated coverage report") { Arity = ArgumentArity.ZeroOrOne }; var verbosity = new Option(new[] { "--verbosity", "-v" }, () => LogLevel.Normal, "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.") { Arity = ArgumentArity.ZeroOrOne }; - var formats = new Option(new[] { "--format", "-f" }, () => new[] { "json" }, "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore }; + var formats = new Option(new[] { "--format", "-f" }, () => new[] { "json" }, "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var threshold = new Option("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne }; var thresholdTypes = new Option>("--threshold-type", () => new List(new string[] { "line", "branch", "method" }), "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); var thresholdStat = new Option("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrMore }; - var excludeFilters = new Option("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore }; - var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore }; - var excludedSourceFiles = new Option("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore }; - var includeDirectories = new Option("--include-directory", "Include directories containing additional assemblies to be instrumented.") { Arity = ArgumentArity.ZeroOrMore }; - var excludeAttributes = new Option("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrOne }; + var excludeFilters = new Option("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var excludedSourceFiles = new Option("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var includeDirectories = new Option("--include-directory", "Include directories containing additional assemblies to be instrumented.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; + var excludeAttributes = new Option("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrOne, AllowMultipleArgumentsPerToken = true }; var includeTestAssembly = new Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.") { Arity = ArgumentArity.Zero }; var singleHit = new Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location") { Arity = ArgumentArity.Zero }; var skipAutoProp = new Option("--skipautoprops", "Neither track nor record auto-implemented properties.") { Arity = ArgumentArity.Zero }; var mergeWith = new Option("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne }; var useSourceLink = new Option("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero }; - var doesNotReturnAttributes = new Option("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore }; + var doesNotReturnAttributes = new Option("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var excludeAssembliesWithoutSources = new Option("--exclude-assemblies-without-sources", "Specifies behaviour of heuristic to ignore assemblies with missing source documents.") { Arity = ArgumentArity.ZeroOrOne }; var sourceMappingFile = new Option("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne }; diff --git a/src/coverlet.core/CoverageResult.cs b/src/coverlet.core/CoverageResult.cs index 3cc9ce084..c547f6a40 100644 --- a/src/coverlet.core/CoverageResult.cs +++ b/src/coverlet.core/CoverageResult.cs @@ -24,7 +24,7 @@ internal class Branches : List { } internal class Method { [JsonConstructor] - internal Method() + public Method() { Lines = []; Branches = []; diff --git a/src/coverlet.core/coverlet.core.csproj b/src/coverlet.core/coverlet.core.csproj index 0492a403b..77ef61484 100644 --- a/src/coverlet.core/coverlet.core.csproj +++ b/src/coverlet.core/coverlet.core.csproj @@ -7,18 +7,18 @@ - - - - + + + + - + - - + + From 9ee7b8fbe4b8f5963405c47d10d7fb6eb8eb80c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Mon, 26 Feb 2024 08:50:34 +0100 Subject: [PATCH 3/9] Broken exclude-by-attribute feature in `coverlet.console` (#1627) --- Documentation/Changelog.md | 12 ++++++++++++ Documentation/GlobalTool.md | 8 +++++++- src/coverlet.console/Program.cs | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 22edce12a..18851252f 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Fixed +- Exception when multiple exclude-by-attribute filters specified [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) + +### Improvements +- More concise options to specify multiple parameters in coverlet.console [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) + +## Release date 2024-02-19 +### Packages +coverlet.msbuild 6.0.1 +coverlet.console 6.0.1 +coverlet.collector 6.0.1 + ### Fixed - Uncovered lines in .NET 8 for inheriting records [#1555](https://github.com/coverlet-coverage/coverlet/issues/1555) - Fix record constructors not covered when SkipAutoProps is true [#1561](https://github.com/coverlet-coverage/coverlet/issues/1561) diff --git a/Documentation/GlobalTool.md b/Documentation/GlobalTool.md index 4b3d2ab33..9627167d0 100644 --- a/Documentation/GlobalTool.md +++ b/Documentation/GlobalTool.md @@ -42,12 +42,18 @@ Options: -?, -h, --help Show help and usage information ``` -NB. For a [multiple value] options you have to specify values multiple times i.e. +NB. For [multiple value] options you can either specify values multiple times i.e. ```shell --exclude-by-attribute 'Obsolete' --exclude-by-attribute 'GeneratedCode' --exclude-by-attribute 'CompilerGenerated' ``` +or pass the multiple values as space separated sequence, i.e. + +```shell +--exclude-by-attribute "Obsolete" "GeneratedCode" "CompilerGenerated" +``` + For `--merge-with` [check the sample](Examples.md). ## Code Coverage diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index 8782747a9..2a4684244 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -40,7 +40,7 @@ static int Main(string[] args) var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var excludedSourceFiles = new Option("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var includeDirectories = new Option("--include-directory", "Include directories containing additional assemblies to be instrumented.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; - var excludeAttributes = new Option("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrOne, AllowMultipleArgumentsPerToken = true }; + var excludeAttributes = new Option("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var includeTestAssembly = new Option("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.") { Arity = ArgumentArity.Zero }; var singleHit = new Option("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location") { Arity = ArgumentArity.Zero }; var skipAutoProp = new Option("--skipautoprops", "Neither track nor record auto-implemented properties.") { Arity = ArgumentArity.Zero }; From 783c482bbb1d59e02e6859fd5397ebda95774f3c Mon Sep 17 00:00:00 2001 From: Amir Date: Mon, 26 Feb 2024 12:56:34 +0330 Subject: [PATCH 4/9] Add regex evaluation timeout (#1630) --- src/coverlet.core/Helpers/InstrumentationHelper.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index f0af9b31c..f6a35f73a 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -24,6 +24,8 @@ internal class InstrumentationHelper : IInstrumentationHelper private readonly IFileSystem _fileSystem; private readonly ISourceRootTranslator _sourceRootTranslator; private ILogger _logger; + private static readonly RegexOptions s_regexOptions = + RegexOptions.Multiline | RegexOptions.Compiled | RegexOptions.IgnoreCase; public InstrumentationHelper(IProcessExitHandler processExitHandler, IRetryHelper retryHelper, IFileSystem fileSystem, ILogger logger, ISourceRootTranslator sourceRootTranslator) { @@ -331,7 +333,7 @@ public bool IsValidFilterExpression(string filter) if (filter.EndsWith("]")) return false; - if (new Regex(@"[^\w*]").IsMatch(filter.Replace(".", "").Replace("?", "").Replace("[", "").Replace("]", ""))) + if (new Regex(@"[^\w*]", s_regexOptions, TimeSpan.FromSeconds(10)).IsMatch(filter.Replace(".", "").Replace("?", "").Replace("[", "").Replace("]", ""))) return false; return true; @@ -358,7 +360,7 @@ public bool IsModuleExcluded(string module, string[] excludeFilters) #pragma warning restore IDE0057 // Use range operator modulePattern = WildcardToRegex(modulePattern); - var regex = new Regex(modulePattern); + var regex = new Regex(modulePattern, s_regexOptions, TimeSpan.FromSeconds(10)); if (regex.IsMatch(module)) return true; @@ -387,7 +389,7 @@ public bool IsModuleIncluded(string module, string[] includeFilters) modulePattern = WildcardToRegex(modulePattern); - var regex = new Regex(modulePattern); + var regex = new Regex(modulePattern, s_regexOptions, TimeSpan.FromSeconds(10)); if (regex.IsMatch(module)) return true; @@ -421,7 +423,7 @@ public bool IsTypeIncluded(string module, string type, string[] includeFilters) } public bool IsLocalMethod(string method) - => new Regex(WildcardToRegex("<*>*__*|*")).IsMatch(method); + => new Regex(WildcardToRegex("<*>*__*|*"), s_regexOptions, TimeSpan.FromSeconds(10)).IsMatch(method); public void SetLogger(ILogger logger) { @@ -443,7 +445,7 @@ private static bool IsTypeFilterMatch(string module, string type, string[] filte typePattern = WildcardToRegex(typePattern); modulePattern = WildcardToRegex(modulePattern); - if (new Regex(typePattern).IsMatch(type) && new Regex(modulePattern).IsMatch(module)) + if (new Regex(typePattern, s_regexOptions, TimeSpan.FromSeconds(10)).IsMatch(type) && new Regex(modulePattern, s_regexOptions, TimeSpan.FromSeconds(10)).IsMatch(module)) return true; } From 813f36c5a856ac7478ca0734e2234613ba201d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Thu, 7 Mar 2024 20:49:44 +0100 Subject: [PATCH 5/9] Fix issue 1634 (#1635) Co-authored-by: David Mueller x --- Documentation/Changelog.md | 1 + src/coverlet.console/Program.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 18851252f..d2aa95236 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased ### Fixed +- Threshold-stat triggers error [#1634](https://github.com/coverlet-coverage/coverlet/issues/1634) - Exception when multiple exclude-by-attribute filters specified [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) ### Improvements diff --git a/src/coverlet.console/Program.cs b/src/coverlet.console/Program.cs index 2a4684244..864df117f 100644 --- a/src/coverlet.console/Program.cs +++ b/src/coverlet.console/Program.cs @@ -35,7 +35,7 @@ static int Main(string[] args) var formats = new Option(new[] { "--format", "-f" }, () => new[] { "json" }, "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var threshold = new Option("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne }; var thresholdTypes = new Option>("--threshold-type", () => new List(new string[] { "line", "branch", "method" }), "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method"); - var thresholdStat = new Option("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrMore }; + var thresholdStat = new Option("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrOne }; var excludeFilters = new Option("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var includeFilters = new Option("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; var excludedSourceFiles = new Option("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true }; From 6bd8783058d3a297b107e2613f667c1d0f368a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Fri, 8 Mar 2024 01:49:45 +0100 Subject: [PATCH 6/9] Remove usage of System.Text.Json for now (#1637) * started moving back to newtonsoft json * removed system text json * update change log * nit --------- Co-authored-by: David Mueller x --- Directory.Packages.props | 1 - Documentation/Changelog.md | 1 + src/coverlet.core/Coverage.cs | 18 ++--- src/coverlet.core/CoverageResult.cs | 8 +-- .../Instrumentation/CecilAssemblyResolver.cs | 21 +++--- src/coverlet.core/Reporters/JsonReporter.cs | 11 +-- src/coverlet.core/coverlet.core.csproj | 2 +- .../Coverage/CoverageTests.cs | 68 +++++++------------ 8 files changed, 47 insertions(+), 83 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 580a1c491..6c94f40a1 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -44,7 +44,6 @@ - diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index d2aa95236..68fa8076a 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Threshold-stat triggers error [#1634](https://github.com/coverlet-coverage/coverlet/issues/1634) +- Fixed coverlet collector 6.0.1 requires dotnet sdk 8 [#1625](https://github.com/coverlet-coverage/coverlet/issues/1625) - Exception when multiple exclude-by-attribute filters specified [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) ### Improvements diff --git a/src/coverlet.core/Coverage.cs b/src/coverlet.core/Coverage.cs index 3e0f46216..e057a09bb 100644 --- a/src/coverlet.core/Coverage.cs +++ b/src/coverlet.core/Coverage.cs @@ -6,8 +6,8 @@ using System.IO; using System.Linq; using System.Runtime.Serialization; -using System.Text.Json; -using System.Text.Json.Nodes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Coverlet.Core.Abstractions; using Coverlet.Core.Helpers; using Coverlet.Core.Instrumentation; @@ -60,14 +60,6 @@ internal class Coverage public string Identifier { get; } - readonly JsonSerializerOptions _options = new() - { - PropertyNameCaseInsensitive = true, - DictionaryKeyPolicy = JsonNamingPolicy.CamelCase, - IncludeFields = true, - WriteIndented = true - }; - public Coverage(string moduleOrDirectory, CoverageParameters parameters, ILogger logger, @@ -325,7 +317,7 @@ public CoverageResult GetCoverageResult() { _logger.LogInformation($"MergeWith: '{_parameters.MergeWith}'."); string json = _fileSystem.ReadAllText(_parameters.MergeWith); - coverageResult.Merge(JsonSerializer.Deserialize(json, _options)); + coverageResult.Merge(JsonConvert.DeserializeObject(json)); } else { _logger.LogInformation($"MergeWith: file '{_parameters.MergeWith}' does not exist."); @@ -387,8 +379,8 @@ private void CalculateCoverage() var documents = result.Documents.Values.ToList(); if (_parameters.UseSourceLink && result.SourceLink != null) { - JsonNode jObject = JsonNode.Parse(result.SourceLink)["documents"]; - Dictionary sourceLinkDocuments = JsonSerializer.Deserialize>(jObject.ToString()); + JToken jObject = JObject.Parse(result.SourceLink)["documents"]; + Dictionary sourceLinkDocuments = JsonConvert.DeserializeObject>(jObject.ToString()); foreach (Document document in documents) { document.Path = GetSourceLinkUrl(sourceLinkDocuments, document.Path); diff --git a/src/coverlet.core/CoverageResult.cs b/src/coverlet.core/CoverageResult.cs index c547f6a40..00a64568c 100644 --- a/src/coverlet.core/CoverageResult.cs +++ b/src/coverlet.core/CoverageResult.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using System.Text.Json.Serialization; using Coverlet.Core.Enums; using Coverlet.Core.Instrumentation; @@ -23,11 +22,10 @@ internal class Branches : List { } internal class Method { - [JsonConstructor] - public Method() + internal Method() { - Lines = []; - Branches = []; + Lines = new Lines(); + Branches = new Branches(); } public Lines Lines; diff --git a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs index c8e0a4109..49790660e 100644 --- a/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs +++ b/src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs @@ -5,12 +5,12 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Json; using Coverlet.Core.Abstractions; using Coverlet.Core.Exceptions; using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel.Resolution; using Mono.Cecil; +using Newtonsoft.Json.Linq; using NuGet.Versioning; namespace Coverlet.Core.Instrumentation @@ -298,25 +298,24 @@ public RuntimeConfigurationReader(string runtimeConfigFile) { string jsonString = File.ReadAllText(_runtimeConfigFile); - var documentOptions = new JsonDocumentOptions + var jsonLoadSettings = new JsonLoadSettings() { - CommentHandling = JsonCommentHandling.Skip + CommentHandling = CommentHandling.Ignore }; - using var configuration = JsonDocument.Parse(jsonString, documentOptions); + var configuration = JObject.Parse(jsonString, jsonLoadSettings); - JsonElement rootElement = configuration.RootElement; + JToken rootElement = configuration.Root; + JToken runtimeOptionsElement = rootElement["runtimeOptions"]; - JsonElement runtimeOptionsElement = rootElement.GetProperty("runtimeOptions"); - - if (runtimeOptionsElement.TryGetProperty("framework", out JsonElement frameworkElement)) + if (runtimeOptionsElement?["framework"] != null) { - return new[] { (frameworkElement.GetProperty("name").GetString(), frameworkElement.GetProperty("version").GetString()) }; + return new[] { (runtimeOptionsElement["framework"]["name"]?.Value(), runtimeOptionsElement["framework"]["version"]?.Value()) }; } - if (runtimeOptionsElement.TryGetProperty("frameworks", out JsonElement frameworksElement)) + if (runtimeOptionsElement?["frameworks"] != null) { - return frameworksElement.EnumerateArray().Select(x => (x.GetProperty("name").GetString(), x.GetProperty("version").GetString())).ToList(); + return runtimeOptionsElement["frameworks"].Select(x => (x["name"]?.Value(), x["version"]?.Value())).ToList(); } throw new InvalidOperationException($"Unable to read runtime configuration from {_runtimeConfigFile}."); diff --git a/src/coverlet.core/Reporters/JsonReporter.cs b/src/coverlet.core/Reporters/JsonReporter.cs index 62be3373a..e684e8c8a 100644 --- a/src/coverlet.core/Reporters/JsonReporter.cs +++ b/src/coverlet.core/Reporters/JsonReporter.cs @@ -1,9 +1,8 @@ // Copyright (c) Toni Solarin-Sodara // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System.Text.Encodings.Web; -using System.Text.Json; using Coverlet.Core.Abstractions; +using Newtonsoft.Json; namespace Coverlet.Core.Reporters { @@ -17,13 +16,7 @@ internal class JsonReporter : IReporter public string Report(CoverageResult result, ISourceRootTranslator _) { - var options = new JsonSerializerOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - IncludeFields = true, - WriteIndented = true, - }; - return JsonSerializer.Serialize(result.Modules, options); + return JsonConvert.SerializeObject(result.Modules, Formatting.Indented); } } } diff --git a/src/coverlet.core/coverlet.core.csproj b/src/coverlet.core/coverlet.core.csproj index 77ef61484..fd4fe2c2b 100644 --- a/src/coverlet.core/coverlet.core.csproj +++ b/src/coverlet.core/coverlet.core.csproj @@ -13,7 +13,7 @@ - + diff --git a/test/coverlet.core.tests/Coverage/CoverageTests.cs b/test/coverlet.core.tests/Coverage/CoverageTests.cs index 25761f83d..701df8f30 100644 --- a/test/coverlet.core.tests/Coverage/CoverageTests.cs +++ b/test/coverlet.core.tests/Coverage/CoverageTests.cs @@ -2,17 +2,16 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Json.Serialization; using Coverlet.Core.Abstractions; using Coverlet.Core.Helpers; using Coverlet.Core.Instrumentation; using Coverlet.Core.Symbols; using Moq; +using Newtonsoft.Json; using Xunit; namespace Coverlet.Core.Tests @@ -20,16 +19,6 @@ namespace Coverlet.Core.Tests public partial class CoverageTests { private readonly Mock _mockLogger = new(); - readonly JsonSerializerOptions _options = new() - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - IncludeFields = true, - WriteIndented = true, - Converters = - { - new BranchDictionaryConverterFactory() - } - }; [Fact] public void TestCoverage() @@ -102,7 +91,7 @@ public void TestCoverageWithTestAssembly() new SourceRootTranslator(module, _mockLogger.Object, new FileSystem(), new AssemblyAdapter()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + string result = JsonConvert.SerializeObject(coverage.GetCoverageResult(), Formatting.Indented, new BranchDictionaryConverter()); Assert.Contains("coverlet.core.tests.dll", result); @@ -141,7 +130,7 @@ public void TestCoverageMergeWithParameter() var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), parameters, _mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + string result = JsonConvert.SerializeObject(coverage.GetCoverageResult(), Formatting.Indented, new BranchDictionaryConverter()); Assert.Contains("DeepThought.cs", result); @@ -182,7 +171,7 @@ public void TestCoverageMergeWithWrongParameter() var coverage = new Coverage(Path.Combine(directory.FullName, Path.GetFileName(module)), parameters, _mockLogger.Object, instrumentationHelper, new FileSystem(), new SourceRootTranslator(_mockLogger.Object, new FileSystem()), new CecilSymbolHelper()); coverage.PrepareModules(); - string result = JsonSerializer.Serialize(coverage.GetCoverageResult(), _options); + JsonConvert.SerializeObject(coverage.GetCoverageResult()); _mockLogger.Verify(l => l.LogInformation(It.Is(v => v.Equals("MergeWith: file 'FileDoesNotExist.json' does not exist.")), It.IsAny()), Times.Once); @@ -190,43 +179,36 @@ public void TestCoverageMergeWithWrongParameter() } } } -public class BranchDictionaryConverterFactory : JsonConverterFactory -{ - public override bool CanConvert(Type typeToConvert) - { - return typeof(Dictionary).IsAssignableFrom(typeToConvert); - } - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) +public class BranchDictionaryConverter: JsonConverter +{ + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - Type[] genericArgs = typeToConvert.GetGenericArguments(); - Type keyType = genericArgs[0]; - Type valueType = genericArgs[1]; + Type type = value.GetType(); + var keys = (IEnumerable)type.GetProperty("Keys")?.GetValue(value, null); + var values = (IEnumerable)type.GetProperty("Values")?.GetValue(value, null); + IEnumerator valueEnumerator = values.GetEnumerator(); - JsonConverter converter = (JsonConverter)Activator.CreateInstance( - typeof(BranchDictionaryConverter<,>).MakeGenericType(new Type[] { keyType, valueType })); + writer.WriteStartArray(); + foreach (object key in keys) + { + valueEnumerator.MoveNext(); - return converter; + writer.WriteStartArray(); + serializer.Serialize(writer, key); + serializer.Serialize(writer, valueEnumerator.Current); + writer.WriteEndArray(); + } + writer.WriteEndArray(); } -} -public class BranchDictionaryConverter : JsonConverter> -{ - public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { throw new NotImplementedException(); } - public override void Write(Utf8JsonWriter writer, Dictionary value, JsonSerializerOptions options) + public override bool CanConvert(Type objectType) { - writer.WriteStartObject(); - - foreach (KeyValuePair pair in value) - { - writer.WritePropertyName(pair.Key.ToString()); - JsonSerializer.Serialize(writer, pair.Value, options); - } - - writer.WriteEndObject(); + return typeof(Dictionary).IsAssignableFrom(objectType); } } From 892d86e16b15522e10666bbb3aafb1284dfcc5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Fri, 8 Mar 2024 02:16:53 +0100 Subject: [PATCH 7/9] Fix TypeInitializer issue (#1636) * core back to standard, change of condition to msbuild props * update change log * only netstandard * nit * nit --------- Co-authored-by: David Mueller x --- Documentation/Changelog.md | 1 + src/coverlet.collector/coverlet.collector.csproj | 2 +- src/coverlet.core/coverlet.core.csproj | 2 +- .../buildMultiTargeting/coverlet.msbuild.props | 4 ---- src/coverlet.msbuild.tasks/coverlet.msbuild.props | 3 +-- src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj | 5 +---- test/Directory.Build.targets | 3 +-- .../coverlet.integration.determisticbuild.csproj | 1 - 8 files changed, 6 insertions(+), 15 deletions(-) delete mode 100644 src/coverlet.msbuild.tasks/buildMultiTargeting/coverlet.msbuild.props diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 68fa8076a..9cd1203ba 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Threshold-stat triggers error [#1634](https://github.com/coverlet-coverage/coverlet/issues/1634) - Fixed coverlet collector 6.0.1 requires dotnet sdk 8 [#1625](https://github.com/coverlet-coverage/coverlet/issues/1625) +- Type initializer errors after updating from 6.0.0 to 6.0.1 [#1629](https://github.com/coverlet-coverage/coverlet/issues/1629) - Exception when multiple exclude-by-attribute filters specified [#1624](https://github.com/coverlet-coverage/coverlet/issues/1624) ### Improvements diff --git a/src/coverlet.collector/coverlet.collector.csproj b/src/coverlet.collector/coverlet.collector.csproj index fc6145d80..ddb8522ba 100644 --- a/src/coverlet.collector/coverlet.collector.csproj +++ b/src/coverlet.collector/coverlet.collector.csproj @@ -1,6 +1,6 @@ - netstandard2.0;net6.0 + netstandard2.0 coverlet.collector true true diff --git a/src/coverlet.core/coverlet.core.csproj b/src/coverlet.core/coverlet.core.csproj index fd4fe2c2b..5e78d106a 100644 --- a/src/coverlet.core/coverlet.core.csproj +++ b/src/coverlet.core/coverlet.core.csproj @@ -2,7 +2,7 @@ Library - netstandard2.0;net6.0 + netstandard2.0 false diff --git a/src/coverlet.msbuild.tasks/buildMultiTargeting/coverlet.msbuild.props b/src/coverlet.msbuild.tasks/buildMultiTargeting/coverlet.msbuild.props deleted file mode 100644 index ba0c4ed38..000000000 --- a/src/coverlet.msbuild.tasks/buildMultiTargeting/coverlet.msbuild.props +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/coverlet.msbuild.tasks/coverlet.msbuild.props b/src/coverlet.msbuild.tasks/coverlet.msbuild.props index 6642a929d..9403e7702 100644 --- a/src/coverlet.msbuild.tasks/coverlet.msbuild.props +++ b/src/coverlet.msbuild.tasks/coverlet.msbuild.props @@ -19,7 +19,6 @@ - $(MSBuildThisFileDirectory)..\tasks\net6.0\ - $(MSBuildThisFileDirectory)..\tasks\netstandard2.0\ + $(MSBuildThisFileDirectory)..\tasks\netstandard2.0\ diff --git a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj index 07c991a4d..17332caa6 100644 --- a/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj +++ b/src/coverlet.msbuild.tasks/coverlet.msbuild.tasks.csproj @@ -2,7 +2,7 @@ Library - netstandard2.0;net6.0 + netstandard2.0 coverlet.msbuild.tasks true $(TargetsForTfmSpecificContentInPackage);PackBuildOutputs @@ -55,9 +55,6 @@ Always - - Always - Always diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 30e3bcaad..b181fcf29 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -14,8 +14,7 @@ This is required when the coverlet.msbuild imports are made in their src directory (so that msbuild eval works even before they are built) so that they can still find the tooling that will be built by the build. --> - $(RepoRoot)artifacts\bin\coverlet.msbuild.tasks\$(Configuration.ToLowerInvariant())_net6.0\ - $(RepoRoot)artifacts\bin\coverlet.msbuild.tasks\$(Configuration.ToLowerInvariant())_netstandard2.0\ + $(RepoRoot)artifacts\bin\coverlet.msbuild.tasks\$(Configuration.ToLowerInvariant())_netstandard2.0\ diff --git a/test/coverlet.integration.determisticbuild/coverlet.integration.determisticbuild.csproj b/test/coverlet.integration.determisticbuild/coverlet.integration.determisticbuild.csproj index 584a6fef6..af3dd09ac 100644 --- a/test/coverlet.integration.determisticbuild/coverlet.integration.determisticbuild.csproj +++ b/test/coverlet.integration.determisticbuild/coverlet.integration.determisticbuild.csproj @@ -12,7 +12,6 @@ https://api.nuget.org/v3/index.json; $(RepoRoot)artifacts/package/$(Configuration.ToLowerInvariant()) - true From f61bbc7230dc7bb8479bad2aa41528efe6612618 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Mon, 11 Mar 2024 18:33:52 +1000 Subject: [PATCH 8/9] Update docs on new source-mapping-file argument (#1632) * Update docs on new source-mapping-file argument * Update GlobalTool.md --- Documentation/GlobalTool.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/GlobalTool.md b/Documentation/GlobalTool.md index 9627167d0..602a4aea8 100644 --- a/Documentation/GlobalTool.md +++ b/Documentation/GlobalTool.md @@ -37,7 +37,7 @@ Options: --use-source-link Specifies whether to use SourceLink URIs in place of file system paths. --does-not-return-attribute Attributes that mark methods that do not return. --exclude-assemblies-without-sources Specifies behaviour of heuristic to ignore assemblies with missing source documents. - --use-mapping-file Specifies the path to a SourceRootsMappings file. + --source-mapping-file Specifies the path to a SourceRootsMappings file. --version Show version information -?, -h, --help Show help and usage information ``` From 04ba205b93e57ebc02bd61ce57a790ec983de3e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Wed, 13 Mar 2024 00:20:45 +0100 Subject: [PATCH 9/9] new release (#1641) --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 55b26a30b..934880ede 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "6.0.2-preview.{height}", + "version": "6.0.2", "publicReleaseRefSpec": [ "^refs/heads/master$" ],