Skip to content

Commit 5c2a245

Browse files
committed
use System.CommandLine V2.0.0-beta4.24209.3 (latest)
1 parent c27f704 commit 5c2a245

File tree

9 files changed

+87
-63
lines changed

9 files changed

+87
-63
lines changed

.editorconfig

+1
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,4 @@ csharp_style_prefer_top_level_statements = true:silent
227227
csharp_style_prefer_primary_constructors = true:suggestion
228228
csharp_style_expression_bodied_lambdas = true:silent
229229
csharp_style_expression_bodied_local_functions = false:silent
230+
dotnet_diagnostic.IDE0007.severity = suggestion

Directory.Packages.props

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
<PackageVersion Include="ReportGenerator.Core" Version="5.2.1" />
3939
<!--For test issue 809 https://github.com/coverlet-coverage/coverlet/issues/809-->
4040
<PackageVersion Include="LinqKit.Microsoft.EntityFrameworkCore" Version="7.1.4" />
41-
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
41+
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.24209.3" />
42+
<!-- <PackageVersion Include="System.CommandLine.Hosting" Version="0.4.0-alpha.24209.3" />
43+
<PackageVersion Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.24209.3" />-->
4244
<!--To test issue 1104 https://github.com/coverlet-coverage/coverlet/issues/1104-->
4345
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" />
4446
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />

NuGet.config

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<clear />
5+
<!-- Coverlet nightly build feed -->
6+
<add key="coverletNightly" value="https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json" />
7+
<!-- dotnet-libraries feed -->
8+
<add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
9+
<!-- Default nuget feed -->
10+
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
11+
</packageSources>
12+
</configuration>

eng/build.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ steps:
2020
New-Item -ItemType Directory -Path artifacts/package/release -Force
2121
displayName: create folder artifacts/package/$(BuildConfiguration)
2222

23-
- script: dotnet restore
23+
- task: NuGetAuthenticate@1
24+
displayName: Authenticate with NuGet feeds
25+
26+
- script: dotnet restore --configfile NuGet.config
2427
displayName: Restore packages
2528

2629
- script: dotnet build -c $(BuildConfiguration) --no-restore -bl:build.msbuild.binlog

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "8.0.101"
3+
"version": "8.0.300"
44
}
55
}

src/coverlet.console/Program.cs

+60-54
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System;
55
using System.Collections.Generic;
66
using System.CommandLine;
7+
using System.CommandLine.Help;
8+
using System.CommandLine.Parsing;
79
using System.ComponentModel;
810
using System.Diagnostics;
911
using System.Globalization;
@@ -25,32 +27,33 @@ namespace Coverlet.Console
2527
{
2628
public static class Program
2729
{
28-
static int Main(string[] args)
30+
static async Task Main(string[] args)
2931
{
30-
var moduleOrAppDirectory = new Argument<string>("path", "Path to the test assembly or application directory.");
31-
var target = new Option<string>(new[] { "--target", "-t" }, "Path to the test runner application.") { Arity = ArgumentArity.ZeroOrOne, IsRequired = true };
32-
var targs = new Option<string>(new[] { "--targetargs", "-a" }, "Arguments to be passed to the test runner.") { Arity = ArgumentArity.ZeroOrOne };
33-
var output = new Option<string>(new[] { "--output", "-o" }, "Output of the generated coverage report") { Arity = ArgumentArity.ZeroOrOne };
34-
var verbosity = new Option<LogLevel>(new[] { "--verbosity", "-v" }, () => LogLevel.Normal, "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.") { Arity = ArgumentArity.ZeroOrOne };
35-
var formats = new Option<string[]>(new[] { "--format", "-f" }, () => new[] { "json" }, "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
36-
var threshold = new Option<string>("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne };
37-
var thresholdTypes = new Option<List<string>>("--threshold-type", () => new List<string>(new string[] { "line", "branch", "method" }), "Coverage type to apply the threshold to.").FromAmong("line", "branch", "method");
38-
var thresholdStat = new Option<ThresholdStatistic>("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrOne };
39-
var excludeFilters = new Option<string[]>("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
40-
var includeFilters = new Option<string[]>("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
41-
var excludedSourceFiles = new Option<string[]>("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
42-
var includeDirectories = new Option<string[]>("--include-directory", "Include directories containing additional assemblies to be instrumented.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
43-
var excludeAttributes = new Option<string[]>("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
44-
var includeTestAssembly = new Option<bool>("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.") { Arity = ArgumentArity.Zero };
45-
var singleHit = new Option<bool>("--single-hit", "Specifies whether to limit code coverage hit reporting to a single hit for each location") { Arity = ArgumentArity.Zero };
46-
var skipAutoProp = new Option<bool>("--skipautoprops", "Neither track nor record auto-implemented properties.") { Arity = ArgumentArity.Zero };
47-
var mergeWith = new Option<string>("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne };
48-
var useSourceLink = new Option<bool>("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero };
49-
var doesNotReturnAttributes = new Option<string[]>("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
50-
var excludeAssembliesWithoutSources = new Option<string>("--exclude-assemblies-without-sources", "Specifies behaviour of heuristic to ignore assemblies with missing source documents.") { Arity = ArgumentArity.ZeroOrOne };
51-
var sourceMappingFile = new Option<string>("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne };
52-
53-
RootCommand rootCommand = new()
32+
CliArgument<string> moduleOrAppDirectory = new ("path") { Description = "Path to the test assembly or application directory." };
33+
CliOption<string> target = new ("--target", aliases: new[]{ "--target", "-t" }) { Description = "Path to the test runner application." , Arity = ArgumentArity.ZeroOrOne, Required = true };
34+
CliOption<string> targs = new ("--targetargs", aliases: new[] { "--targetargs", "-a" } ) { Description = "Arguments to be passed to the test runner.", Arity = ArgumentArity.ZeroOrOne };
35+
CliOption<string> output = new ("--output", aliases: new[] { "--output", "-o" }) { Description = "Output of the generated coverage report", Arity = ArgumentArity.ZeroOrOne };
36+
CliOption<LogLevel> verbosity = new ("--verbosity", aliases: new[] { "--verbosity", "-v" }) { DefaultValueFactory = (_) => LogLevel.Normal, Description = "Sets the verbosity level of the command. Allowed values are quiet, minimal, normal, detailed.", Arity = ArgumentArity.ZeroOrOne };
37+
CliOption<string[]> formats = new ("--format", aliases: new[] { "--format", "-f" }) { DefaultValueFactory = (_) => new[] { "json" }, Description = "Format of the generated coverage report.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
38+
CliOption<string> threshold = new ("--threshold") { Description = "Exits with error if the coverage % is below value.", Arity = ArgumentArity.ZeroOrOne };
39+
CliOption<List<string>> thresholdTypes = new ("--threshold-type") { DefaultValueFactory = (_) => new List<string>(new string[] { "line", "branch", "method" }), Description = ("Coverage type to apply the threshold to.")};
40+
thresholdTypes.AcceptOnlyFromAmong("line", "branch", "method");
41+
CliOption<ThresholdStatistic> thresholdStat = new ("--threshold-stat") {DefaultValueFactory = (_) => ThresholdStatistic.Minimum, Description = "Coverage statistic used to enforce the threshold value." , Arity = ArgumentArity.ZeroOrOne };
42+
CliOption<string[]> excludeFilters = new ("--exclude") { Description = "Filter expressions to exclude specific modules and types.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
43+
CliOption<string[]> includeFilters = new ("--include") { Description = "Filter expressions to include only specific modules and types.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
44+
CliOption<string[]> excludedSourceFiles = new ("--exclude-by-file") { Description = "Glob patterns specifying source files to exclude.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
45+
CliOption<string[]> includeDirectories = new("--include-directory") { Description = "Include directories containing additional assemblies to be instrumented.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
46+
CliOption<string[]> excludeAttributes = new ("--exclude-by-attribute") { Description = "Attributes to exclude from code coverage.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
47+
CliOption<bool> includeTestAssembly = new ("--include-test-assembly") { Description = "Specifies whether to report code coverage of the test assembly.", Arity = ArgumentArity.Zero };
48+
CliOption<bool> singleHit = new ("--single-hit") { Description = "Specifies whether to limit code coverage hit reporting to a single hit for each location", Arity = ArgumentArity.Zero };
49+
CliOption<bool> skipAutoProp = new ("--skipautoprops") { Description = "Neither track nor record auto-implemented properties.", Arity = ArgumentArity.Zero };
50+
CliOption<string> mergeWith = new ("--merge-with") { Description = "Path to existing coverage result to merge.", Arity = ArgumentArity.ZeroOrOne };
51+
CliOption<bool> useSourceLink = new ("--use-source-link") { Description = "Specifies whether to use SourceLink URIs in place of file system paths.", Arity = ArgumentArity.Zero };
52+
CliOption<string[]> doesNotReturnAttributes = new ("--does-not-return-attribute") { Description = "Attributes that mark methods that do not return", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
53+
CliOption<string> excludeAssembliesWithoutSources = new ("--exclude-assemblies-without-sources") { Description = "Specifies behaviour of heuristic to ignore assemblies with missing source documents.", Arity = ArgumentArity.ZeroOrOne };
54+
CliOption<string> sourceMappingFile = new ("--source-mapping-file") { Description = "Specifies the path to a SourceRootsMappings file.", Arity = ArgumentArity.ZeroOrOne };
55+
56+
CliRootCommand rootCommand = new("Cross platform .NET Core code coverage tool")
5457
{
5558
moduleOrAppDirectory,
5659
target,
@@ -59,7 +62,7 @@ static int Main(string[] args)
5962
verbosity,
6063
formats,
6164
threshold,
62-
thresholdTypes,
65+
//thresholdTypes,
6366
thresholdStat,
6467
excludeFilters,
6568
includeFilters,
@@ -75,38 +78,42 @@ static int Main(string[] args)
7578
excludeAssembliesWithoutSources,
7679
sourceMappingFile
7780
};
81+
rootCommand.Add(new HelpOption());
82+
rootCommand.Add(new VersionOption());
7883

79-
rootCommand.Description = "Cross platform .NET Core code coverage tool";
84+
ParseResult parseResult = CliParser.Parse(rootCommand, args);
8085

81-
rootCommand.SetHandler(async (context) =>
86+
CliConfiguration config = new (rootCommand);
87+
88+
rootCommand.SetAction(async (context) =>
8289
{
83-
string moduleOrAppDirectoryValue = context.ParseResult.GetValueForArgument(moduleOrAppDirectory);
84-
string targetValue = context.ParseResult.GetValueForOption(target);
85-
string targsValue = context.ParseResult.GetValueForOption(targs);
86-
string outputValue = context.ParseResult.GetValueForOption(output);
87-
LogLevel verbosityValue = context.ParseResult.GetValueForOption(verbosity);
88-
string[] formatsValue = context.ParseResult.GetValueForOption(formats);
89-
string thresholdValue = context.ParseResult.GetValueForOption(threshold);
90-
List<string> thresholdTypesValue = context.ParseResult.GetValueForOption(thresholdTypes);
91-
ThresholdStatistic thresholdStatValue = context.ParseResult.GetValueForOption(thresholdStat);
92-
string[] excludeFiltersValue = context.ParseResult.GetValueForOption(excludeFilters);
93-
string[] includeFiltersValue = context.ParseResult.GetValueForOption(includeFilters);
94-
string[] excludedSourceFilesValue = context.ParseResult.GetValueForOption(excludedSourceFiles);
95-
string[] includeDirectoriesValue = context.ParseResult.GetValueForOption(includeDirectories);
96-
string[] excludeAttributesValue = context.ParseResult.GetValueForOption(excludeAttributes);
97-
bool includeTestAssemblyValue = context.ParseResult.GetValueForOption(includeTestAssembly);
98-
bool singleHitValue = context.ParseResult.GetValueForOption(singleHit);
99-
bool skipAutoPropValue = context.ParseResult.GetValueForOption(skipAutoProp);
100-
string mergeWithValue = context.ParseResult.GetValueForOption(mergeWith);
101-
bool useSourceLinkValue = context.ParseResult.GetValueForOption(useSourceLink);
102-
string[] doesNotReturnAttributesValue = context.ParseResult.GetValueForOption(doesNotReturnAttributes);
103-
string excludeAssembliesWithoutSourcesValue = context.ParseResult.GetValueForOption(excludeAssembliesWithoutSources);
104-
string sourceMappingFileValue = context.ParseResult.GetValueForOption(sourceMappingFile);
90+
string moduleOrAppDirectoryValue = parseResult.GetValue(moduleOrAppDirectory);
91+
string targetValue = parseResult.GetValue(target);
92+
string targsValue = parseResult.GetValue(targs);
93+
string outputValue = parseResult.GetValue(output);
94+
LogLevel verbosityValue = parseResult.GetValue(verbosity);
95+
string[] formatsValue = parseResult.GetValue(formats);
96+
string thresholdValue = parseResult.GetValue(threshold);
97+
List<string> thresholdTypesValue = parseResult.GetValue(thresholdTypes);
98+
ThresholdStatistic thresholdStatValue = parseResult.GetValue(thresholdStat);
99+
string[] excludeFiltersValue = parseResult.GetValue(excludeFilters);
100+
string[] includeFiltersValue = parseResult.GetValue(includeFilters);
101+
string[] excludedSourceFilesValue = parseResult.GetValue(excludedSourceFiles);
102+
string[] includeDirectoriesValue = parseResult.GetValue(includeDirectories);
103+
string[] excludeAttributesValue = parseResult.GetValue(excludeAttributes);
104+
bool includeTestAssemblyValue = parseResult.GetValue(includeTestAssembly);
105+
bool singleHitValue = parseResult.GetValue(singleHit);
106+
bool skipAutoPropValue = parseResult.GetValue(skipAutoProp);
107+
string mergeWithValue = parseResult.GetValue(mergeWith);
108+
bool useSourceLinkValue = parseResult.GetValue(useSourceLink);
109+
string[] doesNotReturnAttributesValue = parseResult.GetValue(doesNotReturnAttributes);
110+
string excludeAssembliesWithoutSourcesValue = parseResult.GetValue(excludeAssembliesWithoutSources);
111+
string sourceMappingFileValue = parseResult.GetValue(sourceMappingFile);
105112

106113
if (string.IsNullOrEmpty(moduleOrAppDirectoryValue) || string.IsNullOrWhiteSpace(moduleOrAppDirectoryValue))
107114
throw new ArgumentException("No test assembly or application directory specified.");
108115

109-
var taskStatus = await HandleCommand(moduleOrAppDirectoryValue,
116+
int taskStatus = await HandleCommand(moduleOrAppDirectoryValue,
110117
targetValue,
111118
targsValue,
112119
outputValue,
@@ -128,10 +135,10 @@ static int Main(string[] args)
128135
doesNotReturnAttributesValue,
129136
excludeAssembliesWithoutSourcesValue,
130137
sourceMappingFileValue);
131-
context.ExitCode = taskStatus;
138+
//context.ExitCode = taskStatus;
132139

133140
});
134-
return rootCommand.Invoke(args);
141+
await config.InvokeAsync(args).ConfigureAwait(false);
135142
}
136143
private static Task<int> HandleCommand(string moduleOrAppDirectory,
137144
string target,
@@ -385,7 +392,6 @@ string sourceMappingFile
385392

386393
return Task.FromResult(exitCode);
387394

388-
389395
}
390396

391397
catch (Win32Exception we) when (we.Source == "System.Diagnostics.Process")

src/coverlet.core/Coverage.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public CoveragePrepareResult PrepareModules()
108108
_parameters.IncludeFilters = _parameters.IncludeFilters?.Where(f => _instrumentationHelper.IsValidFilterExpression(f)).ToArray();
109109

110110
IReadOnlyList<string> validModules = _instrumentationHelper.SelectModules(modules, _parameters.IncludeFilters, _parameters.ExcludeFilters).ToList();
111-
foreach (var excludedModule in modules.Except(validModules))
111+
foreach (string excludedModule in modules.Except(validModules))
112112
{
113113
_logger.LogVerbose($"Excluded module: '{excludedModule}'");
114114
}

test/coverlet.integration.tests/DeterministicBuild.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ private static void DeleteTestIntermediateFiles(string testResultsPath)
300300
{
301301
if (Directory.Exists(testResultsPath))
302302
{
303-
DirectoryInfo hdDirectory = new DirectoryInfo(testResultsPath);
303+
DirectoryInfo hdDirectory = new (testResultsPath);
304304

305305
// search for directory "In" which has second copy e.g. '_fv-az365-374_2023-10-10_14_26_42\In\fv-az365-374\coverage.json'
306306
DirectoryInfo[] intermediateFolder = hdDirectory.GetDirectories("In", SearchOption.AllDirectories);
@@ -316,7 +316,7 @@ private static void DeleteLogFiles(string directory)
316316
{
317317
if (Directory.Exists(directory))
318318
{
319-
DirectoryInfo hdDirectory = new DirectoryInfo(directory);
319+
DirectoryInfo hdDirectory = new (directory);
320320
FileInfo[] filesInDir = hdDirectory.GetFiles("log.*.txt");
321321

322322
foreach (FileInfo foundFile in filesInDir)
@@ -344,7 +344,7 @@ private static void DeleteCoverageFiles(string directory)
344344
{
345345
if (Directory.Exists(directory))
346346
{
347-
DirectoryInfo hdDirectory = new DirectoryInfo(directory);
347+
DirectoryInfo hdDirectory = new (directory);
348348
FileInfo[] filesInDir = hdDirectory.GetFiles("coverage.cobertura.xml");
349349

350350
foreach (FileInfo foundFile in filesInDir)

test/coverlet.tests.projectsample.aspmvcrazor/Program.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
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-
var builder = WebApplication.CreateBuilder(args);
4+
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
55

66
// Add services to the container.
77
builder.Services.AddRazorPages();
88

9-
var app = builder.Build();
9+
WebApplication app = builder.Build();
1010

1111
// Configure the HTTP request pipeline.
1212
if (!app.Environment.IsDevelopment())

0 commit comments

Comments
 (0)