Skip to content

Commit ee6d285

Browse files
committed
use .NET 8.0 assembies for coverlet.core and remove Newtonsoft.Json
1 parent 47cdd27 commit ee6d285

File tree

18 files changed

+129
-89
lines changed

18 files changed

+129
-89
lines changed

Directory.Packages.props

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
vstest 17.8 version
4040
NuGetFrameworksVersion is defined here https://github.com/microsoft/vstest/blob/9a0c41811637edf4afe0e265e08fdd1cb18109ed/eng/Versions.props#L94C1-L94C1
4141
-->
42-
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
4342
<PackageVersion Include="NuGet.Frameworks" Version="$(NugetPackageVersion)" />
4443
<PackageVersion Include="NuGet.Packaging" Version="$(NugetPackageVersion)" />
4544
<PackageVersion Include="NuGet.Versioning" Version="$(NugetPackageVersion)" />

README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ Coverlet supports only SDK-style projects https://docs.microsoft.com/en-us/visua
4444
```bash
4545
dotnet add package coverlet.collector
4646
```
47-
48-
N.B. You **MUST** add package only to test projects and if you create xunit test projects (`dotnet new xunit`) you'll find the reference already present in `csproj` file because Coverlet is the default coverage tool for every .NET Core and >= .NET 6 applications, you've only to update to last version if needed. Do not add `coverlet.collector` and `coverlet.msbuild` package in a test project.
47+
> [!NOTE]
48+
> You **MUST** add package only to test projects and if you create xunit test projects (`dotnet new xunit`) you will find the reference already present in `csproj` file because Coverlet is the default coverage tool for every .NET Core and >= *.NET 8* applications, you've only to update to last version if needed. Add `coverlet.collector` *OR* `coverlet.msbuild` package in a test project.
4949
5050
### Usage (coverlet.collector)
5151

@@ -61,11 +61,11 @@ See [documentation](Documentation/VSTestIntegration.md) for advanced usage.
6161

6262
#### Requirements (coverlet.collector)
6363

64-
* _You need to be running .NET 6.0 SDK v6.0.316 or newer_
65-
* _You need to reference version 17.5.0 and above of Microsoft.NET.Test.Sdk_
64+
* _You need to be running .NET 8.0 SDK v8.0.112 or newer_
65+
* _You need to reference version 17.12.0 and above of Microsoft.NET.Test.Sdk_
6666

6767
```xml
68-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
68+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
6969
```
7070

7171
### MSBuild Integration (suffers of possible [known issue](https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/KnownIssues.md#1-vstest-stops-process-execution-earlydotnet-test))
@@ -120,7 +120,7 @@ See [documentation](Documentation/GlobalTool.md) for advanced usage.
120120

121121
.NET global tools rely on a .NET Core runtime installed on your machine https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools#what-could-go-wrong
122122

123-
.NET Coverlet global tool requires _.NET Core 2.2 and above_
123+
.NET Coverlet global tool requires _.NET 8.0 or above_
124124

125125
## How It Works
126126

src/coverlet.core/Coverage.cs

+17-8
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
using System.IO;
77
using System.Linq;
88
using System.Runtime.Serialization;
9+
using System.Text.Json;
10+
using System.Text.Json.Nodes;
911
using Coverlet.Core.Abstractions;
1012
using Coverlet.Core.Helpers;
1113
using Coverlet.Core.Instrumentation;
12-
using Newtonsoft.Json;
13-
using Newtonsoft.Json.Linq;
1414

1515
namespace Coverlet.Core
1616
{
@@ -60,6 +60,14 @@ internal class Coverage
6060

6161
public string Identifier { get; }
6262

63+
readonly JsonSerializerOptions _options = new()
64+
{
65+
PropertyNameCaseInsensitive = true,
66+
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
67+
IncludeFields = true,
68+
WriteIndented = true
69+
};
70+
6371
public Coverage(string moduleOrDirectory,
6472
CoverageParameters parameters,
6573
ILogger logger,
@@ -313,7 +321,7 @@ public CoverageResult GetCoverageResult()
313321
{
314322
_logger.LogInformation($"MergeWith: '{_parameters.MergeWith}'.");
315323
string json = _fileSystem.ReadAllText(_parameters.MergeWith);
316-
coverageResult.Merge(JsonConvert.DeserializeObject<Modules>(json));
324+
coverageResult.Merge(JsonSerializer.Deserialize<Modules>(json, _options));
317325
}
318326
else
319327
{
@@ -366,8 +374,8 @@ private void CalculateCoverage()
366374
var documents = result.Documents.Values.ToList();
367375
if (_parameters.UseSourceLink && result.SourceLink != null)
368376
{
369-
JToken jObject = JObject.Parse(result.SourceLink)["documents"];
370-
Dictionary<string, string> sourceLinkDocuments = JsonConvert.DeserializeObject<Dictionary<string, string>>(jObject.ToString());
377+
JsonNode jObject = JsonNode.Parse(result.SourceLink)["documents"];
378+
Dictionary<string, string> sourceLinkDocuments = JsonSerializer.Deserialize<Dictionary<string, string>>(jObject.ToString());
371379
foreach (Document document in documents)
372380
{
373381
document.Path = GetSourceLinkUrl(sourceLinkDocuments, document.Path);
@@ -480,9 +488,9 @@ internal string GetSourceLinkUrl(Dictionary<string, string> sourceLinkDocuments,
480488
{
481489
string key = sourceLinkDocument.Key;
482490
if (Path.GetFileName(key) != "*") continue;
483-
491+
#pragma warning disable IDE0057
484492
IReadOnlyList<SourceRootMapping> rootMapping = _sourceRootTranslator.ResolvePathRoot(key.Substring(0, key.Length - 1));
485-
493+
#pragma warning restore IDE0057
486494
foreach (string keyMapping in rootMapping is null ? [key] : new List<string>(rootMapping.Select(m => m.OriginalPath)))
487495
{
488496
string directoryDocument = Path.GetDirectoryName(document);
@@ -494,8 +502,9 @@ internal string GetSourceLinkUrl(Dictionary<string, string> sourceLinkDocuments,
494502
{
495503
if (!directoryDocument.StartsWith(sourceLinkRoot + Path.DirectorySeparatorChar))
496504
continue;
497-
505+
#pragma warning disable IDE0057
498506
relativePath = directoryDocument.Substring(sourceLinkRoot.Length + 1);
507+
#pragma warning restore IDE0057
499508
}
500509

501510
if (relativePathOfBestMatch.Length == 0)

src/coverlet.core/CoverageResult.cs

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.Linq;
6+
using System.Text.Json.Serialization;
67
using Coverlet.Core.Enums;
78
using Coverlet.Core.Instrumentation;
89

@@ -22,6 +23,7 @@ internal class Branches : List<BranchInfo> { }
2223

2324
internal class Method
2425
{
26+
[JsonConstructor]
2527
internal Method()
2628
{
2729
Lines = [];

src/coverlet.core/Exceptions.cs

-8
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,17 @@
55

66
namespace Coverlet.Core.Exceptions
77
{
8-
[Serializable]
98
public class CoverletException : Exception
109
{
1110
public CoverletException() { }
1211
public CoverletException(string message) : base(message) { }
1312
public CoverletException(string message, System.Exception inner) : base(message, inner) { }
14-
protected CoverletException(
15-
System.Runtime.Serialization.SerializationInfo info,
16-
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
1713
}
1814

19-
[Serializable]
2015
internal class CecilAssemblyResolutionException : CoverletException
2116
{
2217
public CecilAssemblyResolutionException() { }
2318
public CecilAssemblyResolutionException(string message) : base(message) { }
2419
public CecilAssemblyResolutionException(string message, System.Exception inner) : base(message, inner) { }
25-
protected CecilAssemblyResolutionException(
26-
System.Runtime.Serialization.SerializationInfo info,
27-
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
2820
}
2921
}

src/coverlet.core/Helpers/InstrumentationHelper.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -415,17 +415,21 @@ private static string GetIncludeModuleKeysForValidFilters(char escapeSymbol, str
415415
}
416416

417417
private static string CreateRegexExcludePattern(IEnumerable<string> filters, char escapeSymbol)
418-
//only look for module filters here, types will be filtered out when instrumenting
418+
//only look for module filters here, types will be filtered out when instrumenting
419+
#pragma warning disable IDE0057 // Use range operator
419420
=> CreateRegexPattern(filters, escapeSymbol, filter => filter.Substring(filter.IndexOf(']') + 1) == "*");
421+
#pragma warning restore IDE0057 // Use range operator
420422

421423
private static string CreateRegexIncludePattern(IEnumerable<string> filters, char escapeSymbol) =>
422424
CreateRegexPattern(filters, escapeSymbol);
423425

424426
private static string CreateRegexPattern(IEnumerable<string> filters, char escapeSymbol, Func<string, bool> filterPredicate = null)
425427
{
426428
IEnumerable<string> filteredFilters = filterPredicate != null ? filters.Where(filterPredicate) : filters;
429+
#pragma warning disable IDE0057 // Use range operator
427430
IEnumerable<string> regexPatterns = filteredFilters.Select(x =>
428431
$"{escapeSymbol}{WildcardToRegex(x.Substring(1, x.IndexOf(']') - 1)).Trim('^', '$')}{escapeSymbol}");
432+
#pragma warning restore IDE0057 // Use range operator
429433
return string.Join("|", regexPatterns);
430434
}
431435

src/coverlet.core/Instrumentation/CecilAssemblyResolver.cs

+15-12
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
using System.Collections.Generic;
66
using System.IO;
77
using System.Linq;
8+
using System.Text.Json;
89
using Coverlet.Core.Abstractions;
910
using Coverlet.Core.Exceptions;
1011
using Microsoft.Extensions.DependencyModel;
1112
using Microsoft.Extensions.DependencyModel.Resolution;
1213
using Mono.Cecil;
13-
using Newtonsoft.Json.Linq;
1414
using NuGet.Versioning;
1515

1616
namespace Coverlet.Core.Instrumentation
@@ -296,29 +296,32 @@ public RuntimeConfigurationReader(string runtimeConfigFile)
296296
{
297297
string jsonString = File.ReadAllText(_runtimeConfigFile);
298298

299-
var jsonLoadSettings = new JsonLoadSettings()
299+
var documentOptions = new JsonDocumentOptions
300300
{
301-
CommentHandling = CommentHandling.Ignore
301+
CommentHandling = JsonCommentHandling.Skip
302302
};
303303

304-
var configuration = JObject.Parse(jsonString, jsonLoadSettings);
304+
using var configuration = JsonDocument.Parse(jsonString, documentOptions);
305305

306-
JToken rootElement = configuration.Root;
307-
JToken runtimeOptionsElement = rootElement["runtimeOptions"];
306+
JsonElement rootElement = configuration.RootElement;
307+
JsonElement runtimeOptionsElement = rootElement.GetProperty("runtimeOptions");
308308

309-
if (runtimeOptionsElement?["framework"] != null)
309+
if (runtimeOptionsElement.TryGetProperty("framework", out JsonElement frameworkElement))
310310
{
311-
return [(runtimeOptionsElement["framework"]["name"]?.Value<string>(), runtimeOptionsElement["framework"]["version"]?.Value<string>())];
311+
return new List<(string, string)>
312+
{
313+
(runtimeOptionsElement.GetProperty("framework").GetProperty("name").GetString(), runtimeOptionsElement.GetProperty("framework").GetProperty("version").GetString())
314+
};
312315
}
313316

314-
if (runtimeOptionsElement?["frameworks"] != null)
317+
if (runtimeOptionsElement.TryGetProperty("frameworks", out JsonElement frameworksElement))
315318
{
316-
return runtimeOptionsElement["frameworks"].Select(x => (x["name"]?.Value<string>(), x["version"]?.Value<string>())).ToList();
319+
return frameworksElement.EnumerateArray().Select(x => (x.GetProperty("name").GetString(), x.GetProperty("version").GetString())).ToList();
317320
}
318321

319-
if (runtimeOptionsElement?["includedFrameworks"] != null)
322+
if (runtimeOptionsElement.TryGetProperty("includedFrameworks", out JsonElement runtimeoptionselement))
320323
{
321-
return runtimeOptionsElement["includedFrameworks"].Select(x => (x["name"]?.Value<string>(), x["version"]?.Value<string>())).ToList();
324+
return runtimeoptionselement.EnumerateArray().Select(x => (x.GetProperty("name").GetString(), x.GetProperty("version").GetString())).ToList();
322325
}
323326

324327
throw new InvalidOperationException($"Unable to read runtime configuration from {_runtimeConfigFile}.");

src/coverlet.core/Reporters/JsonReporter.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// Copyright (c) Toni Solarin-Sodara
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System.Text.Encodings.Web;
5+
using System.Text.Json;
46
using Coverlet.Core.Abstractions;
5-
using Newtonsoft.Json;
67

78
namespace Coverlet.Core.Reporters
89
{
@@ -16,7 +17,13 @@ internal class JsonReporter : IReporter
1617

1718
public string Report(CoverageResult result, ISourceRootTranslator _)
1819
{
19-
return JsonConvert.SerializeObject(result.Modules, Formatting.Indented);
20+
var options = new JsonSerializerOptions
21+
{
22+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
23+
IncludeFields = true,
24+
WriteIndented = true,
25+
};
26+
return JsonSerializer.Serialize(result.Modules, options);
2027
}
2128
}
2229
}
+16-11
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,30 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Library</OutputType>
5-
<TargetFramework>netstandard2.0</TargetFramework>
5+
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
66
<IsPackable>false</IsPackable>
7+
<NoWarn>$(NoWarn);IDE0057</NoWarn>
78
</PropertyGroup>
89

910
<ItemGroup>
10-
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" VersionOverride="6.0.0" />
11-
<PackageReference Include="Microsoft.Extensions.DependencyModel" VersionOverride="6.0.2" />
12-
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" VersionOverride="6.0.0" />
13-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" VersionOverride="6.0.2" />
11+
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
12+
<PackageReference Include="Microsoft.Extensions.DependencyModel" />
13+
<PackageReference Include="Microsoft.Extensions.FileSystemGlobbing" />
14+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
1415
<PackageReference Include="Mono.Cecil" />
1516
<PackageReference Include="NuGet.Versioning" />
16-
<PackageReference Include="Newtonsoft.Json" />
17-
<PackageReference Include="System.Text.Json" VersionOverride="6.0.11" />
17+
<PackageReference Include="System.Text.Json" />
18+
</ItemGroup>
19+
20+
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.0'">
21+
<PackageReference Include="System.Reflection.Metadata" />
22+
<PackageReference Include="System.Collections.Immutable" />
23+
</ItemGroup>
24+
25+
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
1826
<PackageReference Include="System.Reflection.Metadata" VersionOverride="$(SystemReflectionMetadataVersion)" />
1927
<PackageReference Include="System.Collections.Immutable" VersionOverride="$(SystemCollectionsImmutableVersion)" />
20-
<PackageReference Include="System.Buffers" />
21-
<PackageReference Include="System.Memory" />
22-
<PackageReference Include="System.Threading.Tasks.Extensions" />
2328
</ItemGroup>
2429

2530
</Project>

src/coverlet.msbuild.tasks/coverlet.msbuild.targets

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<PropertyGroup>
77
<_CoverletSdkNETCoreSdkVersion>$(NETCoreSdkVersion)</_CoverletSdkNETCoreSdkVersion>
88
<_CoverletSdkNETCoreSdkVersion Condition="$(_CoverletSdkNETCoreSdkVersion.Contains('-'))">$(_CoverletSdkNETCoreSdkVersion.Split('-')[0])</_CoverletSdkNETCoreSdkVersion>
9-
<_CoverletSdkMinVersionWithDependencyTarget>6.0.100</_CoverletSdkMinVersionWithDependencyTarget>
9+
<_CoverletSdkMinVersionWithDependencyTarget>8.0.100</_CoverletSdkMinVersionWithDependencyTarget>
1010
<_CoverletSourceRootTargetName>CoverletGetPathMap</_CoverletSourceRootTargetName>
1111
<_CoverletSourceRootTargetName Condition="'$([System.Version]::Parse($(_CoverletSdkNETCoreSdkVersion)).CompareTo($([System.Version]::Parse($(_CoverletSdkMinVersionWithDependencyTarget)))))' &gt;= '0' ">InitializeSourceRootMappedPaths</_CoverletSourceRootTargetName>
1212
</PropertyGroup>

0 commit comments

Comments
 (0)