Skip to content

Commit

Permalink
use System.CommandLine V2.0.0-beta4.24209.3 (latest)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bertk committed May 28, 2024
1 parent c27f704 commit 5c2a245
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 63 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,4 @@ csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
dotnet_diagnostic.IDE0007.severity = suggestion
4 changes: 3 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
<PackageVersion Include="ReportGenerator.Core" Version="5.2.1" />
<!--For test issue 809 https://github.com/coverlet-coverage/coverlet/issues/809-->
<PackageVersion Include="LinqKit.Microsoft.EntityFrameworkCore" Version="7.1.4" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.24209.3" />
<!-- <PackageVersion Include="System.CommandLine.Hosting" Version="0.4.0-alpha.24209.3" />
<PackageVersion Include="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.24209.3" />-->
<!--To test issue 1104 https://github.com/coverlet-coverage/coverlet/issues/1104-->
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
Expand Down
12 changes: 12 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<!-- Coverlet nightly build feed -->
<add key="coverletNightly" value="https://pkgs.dev.azure.com/tonerdo/coverlet/_packaging/coverlet-nightly/nuget/v3/index.json" />
<!-- dotnet-libraries feed -->
<add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
<!-- Default nuget feed -->
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
5 changes: 4 additions & 1 deletion eng/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ steps:
New-Item -ItemType Directory -Path artifacts/package/release -Force
displayName: create folder artifacts/package/$(BuildConfiguration)

- script: dotnet restore
- task: NuGetAuthenticate@1
displayName: Authenticate with NuGet feeds

- script: dotnet restore --configfile NuGet.config
displayName: Restore packages

- script: dotnet build -c $(BuildConfiguration) --no-restore -bl:build.msbuild.binlog
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.101"
"version": "8.0.300"
}
}
114 changes: 60 additions & 54 deletions src/coverlet.console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Help;
using System.CommandLine.Parsing;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
Expand All @@ -25,32 +27,33 @@ namespace Coverlet.Console
{
public static class Program
{
static int Main(string[] args)
static async Task Main(string[] args)
{
var moduleOrAppDirectory = new Argument<string>("path", "Path to the test assembly or application directory.");
var target = new Option<string>(new[] { "--target", "-t" }, "Path to the test runner application.") { Arity = ArgumentArity.ZeroOrOne, IsRequired = true };
var targs = new Option<string>(new[] { "--targetargs", "-a" }, "Arguments to be passed to the test runner.") { Arity = ArgumentArity.ZeroOrOne };
var output = new Option<string>(new[] { "--output", "-o" }, "Output of the generated coverage report") { Arity = ArgumentArity.ZeroOrOne };
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 };
var formats = new Option<string[]>(new[] { "--format", "-f" }, () => new[] { "json" }, "Format of the generated coverage report.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var threshold = new Option<string>("--threshold", "Exits with error if the coverage % is below value.") { Arity = ArgumentArity.ZeroOrOne };
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");
var thresholdStat = new Option<ThresholdStatistic>("--threshold-stat", () => ThresholdStatistic.Minimum, "Coverage statistic used to enforce the threshold value.") { Arity = ArgumentArity.ZeroOrOne };
var excludeFilters = new Option<string[]>("--exclude", "Filter expressions to exclude specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var includeFilters = new Option<string[]>("--include", "Filter expressions to include only specific modules and types.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var excludedSourceFiles = new Option<string[]>("--exclude-by-file", "Glob patterns specifying source files to exclude.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var includeDirectories = new Option<string[]>("--include-directory", "Include directories containing additional assemblies to be instrumented.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var excludeAttributes = new Option<string[]>("--exclude-by-attribute", "Attributes to exclude from code coverage.") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var includeTestAssembly = new Option<bool>("--include-test-assembly", "Specifies whether to report code coverage of the test assembly.") { Arity = ArgumentArity.Zero };
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 };
var skipAutoProp = new Option<bool>("--skipautoprops", "Neither track nor record auto-implemented properties.") { Arity = ArgumentArity.Zero };
var mergeWith = new Option<string>("--merge-with", "Path to existing coverage result to merge.") { Arity = ArgumentArity.ZeroOrOne };
var useSourceLink = new Option<bool>("--use-source-link", "Specifies whether to use SourceLink URIs in place of file system paths.") { Arity = ArgumentArity.Zero };
var doesNotReturnAttributes = new Option<string[]>("--does-not-return-attribute", "Attributes that mark methods that do not return") { Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
var excludeAssembliesWithoutSources = new Option<string>("--exclude-assemblies-without-sources", "Specifies behaviour of heuristic to ignore assemblies with missing source documents.") { Arity = ArgumentArity.ZeroOrOne };
var sourceMappingFile = new Option<string>("--source-mapping-file", "Specifies the path to a SourceRootsMappings file.") { Arity = ArgumentArity.ZeroOrOne };

RootCommand rootCommand = new()
CliArgument<string> moduleOrAppDirectory = new ("path") { Description = "Path to the test assembly or application directory." };
CliOption<string> target = new ("--target", aliases: new[]{ "--target", "-t" }) { Description = "Path to the test runner application." , Arity = ArgumentArity.ZeroOrOne, Required = true };
CliOption<string> targs = new ("--targetargs", aliases: new[] { "--targetargs", "-a" } ) { Description = "Arguments to be passed to the test runner.", Arity = ArgumentArity.ZeroOrOne };
CliOption<string> output = new ("--output", aliases: new[] { "--output", "-o" }) { Description = "Output of the generated coverage report", Arity = ArgumentArity.ZeroOrOne };
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 };
CliOption<string[]> formats = new ("--format", aliases: new[] { "--format", "-f" }) { DefaultValueFactory = (_) => new[] { "json" }, Description = "Format of the generated coverage report.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string> threshold = new ("--threshold") { Description = "Exits with error if the coverage % is below value.", Arity = ArgumentArity.ZeroOrOne };
CliOption<List<string>> thresholdTypes = new ("--threshold-type") { DefaultValueFactory = (_) => new List<string>(new string[] { "line", "branch", "method" }), Description = ("Coverage type to apply the threshold to.")};
thresholdTypes.AcceptOnlyFromAmong("line", "branch", "method");
CliOption<ThresholdStatistic> thresholdStat = new ("--threshold-stat") {DefaultValueFactory = (_) => ThresholdStatistic.Minimum, Description = "Coverage statistic used to enforce the threshold value." , Arity = ArgumentArity.ZeroOrOne };
CliOption<string[]> excludeFilters = new ("--exclude") { Description = "Filter expressions to exclude specific modules and types.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string[]> includeFilters = new ("--include") { Description = "Filter expressions to include only specific modules and types.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string[]> excludedSourceFiles = new ("--exclude-by-file") { Description = "Glob patterns specifying source files to exclude.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string[]> includeDirectories = new("--include-directory") { Description = "Include directories containing additional assemblies to be instrumented.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string[]> excludeAttributes = new ("--exclude-by-attribute") { Description = "Attributes to exclude from code coverage.", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<bool> includeTestAssembly = new ("--include-test-assembly") { Description = "Specifies whether to report code coverage of the test assembly.", Arity = ArgumentArity.Zero };
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 };
CliOption<bool> skipAutoProp = new ("--skipautoprops") { Description = "Neither track nor record auto-implemented properties.", Arity = ArgumentArity.Zero };
CliOption<string> mergeWith = new ("--merge-with") { Description = "Path to existing coverage result to merge.", Arity = ArgumentArity.ZeroOrOne };
CliOption<bool> useSourceLink = new ("--use-source-link") { Description = "Specifies whether to use SourceLink URIs in place of file system paths.", Arity = ArgumentArity.Zero };
CliOption<string[]> doesNotReturnAttributes = new ("--does-not-return-attribute") { Description = "Attributes that mark methods that do not return", Arity = ArgumentArity.ZeroOrMore, AllowMultipleArgumentsPerToken = true };
CliOption<string> excludeAssembliesWithoutSources = new ("--exclude-assemblies-without-sources") { Description = "Specifies behaviour of heuristic to ignore assemblies with missing source documents.", Arity = ArgumentArity.ZeroOrOne };
CliOption<string> sourceMappingFile = new ("--source-mapping-file") { Description = "Specifies the path to a SourceRootsMappings file.", Arity = ArgumentArity.ZeroOrOne };

CliRootCommand rootCommand = new("Cross platform .NET Core code coverage tool")
{
moduleOrAppDirectory,
target,
Expand All @@ -59,7 +62,7 @@ static int Main(string[] args)
verbosity,
formats,
threshold,
thresholdTypes,
//thresholdTypes,
thresholdStat,
excludeFilters,
includeFilters,
Expand All @@ -75,38 +78,42 @@ static int Main(string[] args)
excludeAssembliesWithoutSources,
sourceMappingFile
};
rootCommand.Add(new HelpOption());
rootCommand.Add(new VersionOption());

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

rootCommand.SetHandler(async (context) =>
CliConfiguration config = new (rootCommand);

rootCommand.SetAction(async (context) =>
{
string moduleOrAppDirectoryValue = context.ParseResult.GetValueForArgument(moduleOrAppDirectory);
string targetValue = context.ParseResult.GetValueForOption(target);
string targsValue = context.ParseResult.GetValueForOption(targs);
string outputValue = context.ParseResult.GetValueForOption(output);
LogLevel verbosityValue = context.ParseResult.GetValueForOption(verbosity);
string[] formatsValue = context.ParseResult.GetValueForOption(formats);
string thresholdValue = context.ParseResult.GetValueForOption(threshold);
List<string> thresholdTypesValue = context.ParseResult.GetValueForOption(thresholdTypes);
ThresholdStatistic thresholdStatValue = context.ParseResult.GetValueForOption(thresholdStat);
string[] excludeFiltersValue = context.ParseResult.GetValueForOption(excludeFilters);
string[] includeFiltersValue = context.ParseResult.GetValueForOption(includeFilters);
string[] excludedSourceFilesValue = context.ParseResult.GetValueForOption(excludedSourceFiles);
string[] includeDirectoriesValue = context.ParseResult.GetValueForOption(includeDirectories);
string[] excludeAttributesValue = context.ParseResult.GetValueForOption(excludeAttributes);
bool includeTestAssemblyValue = context.ParseResult.GetValueForOption(includeTestAssembly);
bool singleHitValue = context.ParseResult.GetValueForOption(singleHit);
bool skipAutoPropValue = context.ParseResult.GetValueForOption(skipAutoProp);
string mergeWithValue = context.ParseResult.GetValueForOption(mergeWith);
bool useSourceLinkValue = context.ParseResult.GetValueForOption(useSourceLink);
string[] doesNotReturnAttributesValue = context.ParseResult.GetValueForOption(doesNotReturnAttributes);
string excludeAssembliesWithoutSourcesValue = context.ParseResult.GetValueForOption(excludeAssembliesWithoutSources);
string sourceMappingFileValue = context.ParseResult.GetValueForOption(sourceMappingFile);
string moduleOrAppDirectoryValue = parseResult.GetValue(moduleOrAppDirectory);
string targetValue = parseResult.GetValue(target);
string targsValue = parseResult.GetValue(targs);
string outputValue = parseResult.GetValue(output);
LogLevel verbosityValue = parseResult.GetValue(verbosity);
string[] formatsValue = parseResult.GetValue(formats);
string thresholdValue = parseResult.GetValue(threshold);
List<string> thresholdTypesValue = parseResult.GetValue(thresholdTypes);
ThresholdStatistic thresholdStatValue = parseResult.GetValue(thresholdStat);
string[] excludeFiltersValue = parseResult.GetValue(excludeFilters);
string[] includeFiltersValue = parseResult.GetValue(includeFilters);
string[] excludedSourceFilesValue = parseResult.GetValue(excludedSourceFiles);
string[] includeDirectoriesValue = parseResult.GetValue(includeDirectories);
string[] excludeAttributesValue = parseResult.GetValue(excludeAttributes);
bool includeTestAssemblyValue = parseResult.GetValue(includeTestAssembly);
bool singleHitValue = parseResult.GetValue(singleHit);
bool skipAutoPropValue = parseResult.GetValue(skipAutoProp);
string mergeWithValue = parseResult.GetValue(mergeWith);
bool useSourceLinkValue = parseResult.GetValue(useSourceLink);
string[] doesNotReturnAttributesValue = parseResult.GetValue(doesNotReturnAttributes);
string excludeAssembliesWithoutSourcesValue = parseResult.GetValue(excludeAssembliesWithoutSources);
string sourceMappingFileValue = parseResult.GetValue(sourceMappingFile);
if (string.IsNullOrEmpty(moduleOrAppDirectoryValue) || string.IsNullOrWhiteSpace(moduleOrAppDirectoryValue))
throw new ArgumentException("No test assembly or application directory specified.");
var taskStatus = await HandleCommand(moduleOrAppDirectoryValue,
int taskStatus = await HandleCommand(moduleOrAppDirectoryValue,
targetValue,
targsValue,
outputValue,
Expand All @@ -128,10 +135,10 @@ static int Main(string[] args)
doesNotReturnAttributesValue,
excludeAssembliesWithoutSourcesValue,
sourceMappingFileValue);
context.ExitCode = taskStatus;
//context.ExitCode = taskStatus;
});
return rootCommand.Invoke(args);
await config.InvokeAsync(args).ConfigureAwait(false);
}
private static Task<int> HandleCommand(string moduleOrAppDirectory,
string target,
Expand Down Expand Up @@ -385,7 +392,6 @@ string sourceMappingFile

return Task.FromResult(exitCode);


}

catch (Win32Exception we) when (we.Source == "System.Diagnostics.Process")
Expand Down
2 changes: 1 addition & 1 deletion src/coverlet.core/Coverage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public CoveragePrepareResult PrepareModules()
_parameters.IncludeFilters = _parameters.IncludeFilters?.Where(f => _instrumentationHelper.IsValidFilterExpression(f)).ToArray();

IReadOnlyList<string> validModules = _instrumentationHelper.SelectModules(modules, _parameters.IncludeFilters, _parameters.ExcludeFilters).ToList();
foreach (var excludedModule in modules.Except(validModules))
foreach (string excludedModule in modules.Except(validModules))
{
_logger.LogVerbose($"Excluded module: '{excludedModule}'");
}
Expand Down
6 changes: 3 additions & 3 deletions test/coverlet.integration.tests/DeterministicBuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private static void DeleteTestIntermediateFiles(string testResultsPath)
{
if (Directory.Exists(testResultsPath))
{
DirectoryInfo hdDirectory = new DirectoryInfo(testResultsPath);
DirectoryInfo hdDirectory = new (testResultsPath);

// 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'
DirectoryInfo[] intermediateFolder = hdDirectory.GetDirectories("In", SearchOption.AllDirectories);
Expand All @@ -316,7 +316,7 @@ private static void DeleteLogFiles(string directory)
{
if (Directory.Exists(directory))
{
DirectoryInfo hdDirectory = new DirectoryInfo(directory);
DirectoryInfo hdDirectory = new (directory);
FileInfo[] filesInDir = hdDirectory.GetFiles("log.*.txt");

foreach (FileInfo foundFile in filesInDir)
Expand Down Expand Up @@ -344,7 +344,7 @@ private static void DeleteCoverageFiles(string directory)
{
if (Directory.Exists(directory))
{
DirectoryInfo hdDirectory = new DirectoryInfo(directory);
DirectoryInfo hdDirectory = new (directory);
FileInfo[] filesInDir = hdDirectory.GetFiles("coverage.cobertura.xml");

foreach (FileInfo foundFile in filesInDir)
Expand Down
4 changes: 2 additions & 2 deletions test/coverlet.tests.projectsample.aspmvcrazor/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (c) Toni Solarin-Sodara
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

var builder = WebApplication.CreateBuilder(args);
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();
WebApplication app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
Expand Down

0 comments on commit 5c2a245

Please sign in to comment.