diff --git a/.github/workflows/buildAndPublish.yml b/.github/workflows/buildAndPublish.yml
index dbdd022..054a9f0 100644
--- a/.github/workflows/buildAndPublish.yml
+++ b/.github/workflows/buildAndPublish.yml
@@ -42,10 +42,10 @@ jobs:
run: dotnet build -c Release -p:Version=${{ steps.version.outputs.version}}
- name: Run tests
- run: dotnet test -c Release --no-build
+ run: dotnet test -c Release --no-build -l trx --results-directory TestResults
- name: Upload dotnet test results
- uses: dorny/test-reporter@v1.8.0
+ uses: dorny/test-reporter@v1.9.0
if: ${{ !cancelled() }}
with:
name: .NET Tests
diff --git a/.github/workflows/generateDocs.yml b/.github/workflows/generateDocs.yml
index d25c1f3..0509d4b 100644
--- a/.github/workflows/generateDocs.yml
+++ b/.github/workflows/generateDocs.yml
@@ -10,7 +10,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Build documenation site
- uses: nunit/docfx-action@v3.1.0
+ uses: nunit/docfx-action@v3.2.0
with:
args: docs/docfx.json
- name: Upload documentation archive
diff --git a/Directory.Build.props b/Directory.Build.props
index c542c0f..2789807 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,33 +1,34 @@
-
- MGR.CommandLineParser
- netstandard2.0
- bin\$(Configuration)\netstandard2.0\$(MSBuildProjectName).xml
- latest
- true
- false
- false
-
- portable
- true
- true
+
+ MGR.CommandLineParser
+ netstandard2.0
+ bin\$(Configuration)\netstandard2.0\$(MSBuildProjectName).xml
+ latest
+ enable
+ true
+ false
+ false
+
+ portable
+ true
+ true
- Matthias GROSPERRIN
-
- https://github.com/mgrosperrin/commandlineparser
- https://github.com/mgrosperrin/commandlineparser
- MGR.CommandLineParser is a multi-command line parser. It uses System.ComponentModel.DataAnnotations to declare the commands.
- git
- Copyright © Matthias GROSPERRIN
- en-US
- false
- MIT
- trx%3bLogFileName=$(MSBuildProjectName).trx
- $(MSBuildThisFileDirectory)/TestResults/$(TargetFramework)
-
+ Matthias GROSPERRIN
+
+ https://github.com/mgrosperrin/commandlineparser
+ https://github.com/mgrosperrin/commandlineparser
+ MGR.CommandLineParser is a multi-command line parser. It uses System.ComponentModel.DataAnnotations to declare the commands.
+ git
+ Copyright © Matthias GROSPERRIN
+ en-US
+ false
+ MIT
+ trx%3bLogFileName=$(MSBuildProjectName).trx
+ $(MSBuildThisFileDirectory)/TestResults/$(TargetFramework)
+
-
- true
-
+
+ true
+
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 2e1e315..f560a85 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -2,27 +2,25 @@
true
false
- 8.0.0
- 8.0.0
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+
-
-
+
+
all
runtime; build; native; contentfiles; analyzers
diff --git a/MGR.CommandLineParser.sln b/MGR.CommandLineParser.sln
index cdcb309..f9e2242 100644
--- a/MGR.CommandLineParser.sln
+++ b/MGR.CommandLineParser.sln
@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser", "src\MGR.CommandLineParser\MGR.CommandLineParser.csproj", "{EF6019C2-2C4D-4874-BBBF-D76CA30F7E8D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{569ED12A-DA23-4457-B304-6B00C0CB335E}"
+ ProjectSection(SolutionItems) = preProject
+ tests\Directory.Build.props = tests\Directory.Build.props
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser.UnitTests", "tests\MGR.CommandLineParser.UnitTests\MGR.CommandLineParser.UnitTests.csproj", "{22F60D05-F6DB-4410-80AD-E558EF1BDF6F}"
EndProject
@@ -41,6 +44,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MGR.CommandLineParser.Hosti
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj", "{405858FA-1E78-48C7-9915-B558D0F15CAE}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{AF37E9B0-D41E-4CC2-8641-61FA6B28362B}"
+ ProjectSection(SolutionItems) = preProject
+ .github\dependabot.yml = .github\dependabot.yml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BCD738AE-36C9-4CD9-B0F5-EAB942B193DC}"
+ ProjectSection(SolutionItems) = preProject
+ .github\workflows\buildAndPublish.yml = .github\workflows\buildAndPublish.yml
+ .github\workflows\ci.yml = .github\workflows\ci.yml
+ .github\workflows\codeql-analysis.yml = .github\workflows\codeql-analysis.yml
+ .github\workflows\generateDocs.yml = .github\workflows\generateDocs.yml
+ .github\workflows\release.yml = .github\workflows\release.yml
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -92,6 +109,8 @@ Global
{9F5A0142-E0A1-45A2-961E-55611B4440AD} = {FB795A12-C939-492F-9377-4C468D01EF3C}
{40EAA8E2-7AFE-4ED1-A961-35BD7E424985} = {FB795A12-C939-492F-9377-4C468D01EF3C}
{405858FA-1E78-48C7-9915-B558D0F15CAE} = {172E24C2-BF99-4DA9-A7DF-8C0BB44C138D}
+ {AF37E9B0-D41E-4CC2-8641-61FA6B28362B} = {EF849FD3-293F-4CC8-B227-9680CF929A66}
+ {BCD738AE-36C9-4CD9-B0F5-EAB942B193DC} = {AF37E9B0-D41E-4CC2-8641-61FA6B28362B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {827031C5-AE76-4B4C-9503-E13F15B497E9}
diff --git a/docs/class-based/create-class-based-command.md b/docs/class-based/create-class-based-command.md
index 17096aa..5be4d1d 100644
--- a/docs/class-based/create-class-based-command.md
+++ b/docs/class-based/create-class-based-command.md
@@ -1,24 +1,36 @@
# Create a class-based command
-## Implement `ICommand`
+To create a class-based command, you have to create two classes:
+1. one that defines the data associated with the command,
+2. one that implements the logic of the command.
-To create a class-based command, you have to create a class that implements the interface `MGR.CommandLineParser.Command.ICommand` (or [inherit `CommandBase`](#inherit-from-commandbase)).
-The interface provides two members:
+Depending on what basic features you need for your command, you can choose to implement the logic of the command by inheriting from the abstract class `CommandBase` or by implementing the interface `ICommandHandler`.
-1. a property `Arguments` (of type `IList`) that will receive all arguments not mapped to an option,
-2. a method `ExecuteAsync` (that take no parameters and return a `Task`) that is called to execute the command. The returned value is the status code that should be returned as exit code.
+## Inherit from `CommandBase`
+The abstract class `CommandBase` provides implementation for :
-## Inherit from `CommandBase`
-You can inherit from `MGR.CommandLineParser.Command.CommandBase`.
-This abstract class provides:
+- an `--help` option,
+- access to the current `IServiceProvider` via the property `ServiceProvider`,
+- access to the current [IConsole](../extensibility/console.md) via the property `Console`.
-- implementation of an `--help` option,
-- access to the current `IServiceProvider`,
-- access to the current [IConsole](../extensibility/console.md)
-- access to the [ICommandType](/api/MGR.CommandLineParser.Extensibility.Command.ICommandType.html) (which describes the current command)
+When deriving from this class, you have to implement the `ExecuteCommandAsync` that is called when the value of the `--help` option is `false`.
+You also have to make your command data class inherit from `MGR.CommandLineParser.Command.HelpedCommandData` to have the help option implemented.
+It will also give you access to the [ICommandType](/api/MGR.CommandLineParser.Extensibility.Command.ICommandType.html) which describes the current command.
-When deriving from this class, you have to implement the `ExecuteCommandAsync` that is called when the value of the `--help` option is ```false```.
+## Implement `ICommandHandler` and `CommandData`
+
+If you don't need these features, you can implement the interface `ICommandHandler`.
+
+The interface defines a method `ExecuteAsync` to implement which is called to execute the command.
+It takes two parameters:
+1. The data of the command, of type of the generic type argument `TCommandData`,
+2. A `CancellationToken` used to stop the execution of the command.
+
+The method returns a `Task` that represent the status code of the execution of the command (usually the exit code of the program).
+
+The "data" class must inherit `CommandData`, that provides a property `Arguments` (of type `IList`) that will receive all arguments not mapped to an option.
+To define your own opptions, you have to add properties to this class.
## Customize your command
@@ -26,7 +38,7 @@ When deriving from this class, you have to implement the `ExecuteCommandAsync` t
## Add options to you command
-You can add options to your command by simply adding properties to your class.
+You can add options to your command by simply adding properties to your "command data" class.
The properties can have any type, you just have to be sure there is a [converter](../extensibility/converter.md) for this type (see the [list of built-in converters](../extensibility/built-in-converters.md)).
You can customize the behavior of the options with some annotations (the parser supports the annotations from [System.ComponentModel.DataAnnotations](https://docs.microsoft.com/dotnet/api/system.componentmodel.dataannotations)):
diff --git a/docs/index.md b/docs/index.md
index 51f57a7..6c959db 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -6,7 +6,7 @@ It provides an extensible mechanism to provide define commands
and is able to automatically generate help/usage output for all commands.
Built-in providers lets you define command by:
-- [creating a class](class-based/create-class-based-command.md) that implements `MGR.CommandLineParser.Command.ICommand` or inherits `MGR.CommandLineParser.Command.CommandBase` (provides some basic behavior for commands like support of `--help` option)
+- [creating classes](class-based/create-class-based-command.md) that implements `MGR.CommandLineParser.Command.ICommandHandler` for the logic of your command and `MGR.CommandLineParser.Command.CommandData` for the data associated to the command, or inherits `MGR.CommandLineParser.Command.CommandBase` (provides some basic behavior for commands like support of `--help` option)
- [dynamically defining a command that uses a lambda](lambda/create-a-lambda-based-command.md) as execution (via the package `MGR.CommandLineParser.Command.Lambda)
The general syntax on the command line is:
@@ -19,7 +19,6 @@ by a space (` `) or a colon (`:`).
Arguments is a list of non-option string that is passed to the command.
-
There is also some ways to customize others parts of the parser:
- how to display information to the user: the [`IConsole` interface](extensibility/console.md)
diff --git a/generate_docs.ps1 b/generate_docs.ps1
deleted file mode 100644
index e2b0e70..0000000
--- a/generate_docs.ps1
+++ /dev/null
@@ -1,21 +0,0 @@
-Param(
- [switch]$Serve
-)
-$REPO_DIR = Join-Path $PSScriptRoot ".."
-$ARTIFACTS_DIR = Join-Path $REPO_DIR "artifacts"
-$TOOLS_DIR = Join-Path $ARTIFACTS_DIR "tools"
-$docfxRoot = Join-Path $TOOLS_DIR "docfx.console"
-$docfx = Join-Path (Join-Path $docfxRoot "tools") "docfx.exe"
-if (-not (Test-Path $docfx)) {
- mkdir -p $docfxRoot -ErrorAction Ignore | Out-Null
- $temp = (New-TemporaryFile).FullName + ".zip"
- Invoke-WebRequest "https://www.nuget.org/api/v2/package/docfx.console/2.52.0" -O $temp
- Expand-Archive $temp -DestinationPath $docfxRoot
- Remove-Item $temp
-}
-[string[]] $arguments = @()
-if ($Serve) {
- $arguments += '--serve'
-}
-$DocFxJsonPath = Join-Path (Join-Path $REPO_DIR "docs") "docfx.json"
-& $docfx $DocFxJsonPath @arguments
diff --git a/samples/SimpleApp/HostBuilderCalls.cs b/samples/SimpleApp/HostBuilderCalls.cs
index a7e3ef9..5fe7e07 100644
--- a/samples/SimpleApp/HostBuilderCalls.cs
+++ b/samples/SimpleApp/HostBuilderCalls.cs
@@ -6,32 +6,31 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace SimpleApp
+namespace SimpleApp;
+
+internal static class HostBuilderCalls
{
- internal static class HostBuilderCalls
+ internal static async Task CreateAndCallDefaultParserBuilderAsync()
{
- internal static async Task CreateAndCallDefaultParserBuilderAsync()
- {
- var arguments = new[] { "run", "--opt", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
+ var arguments = new[] { "run", "--opt", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- var hostBuilder = new HostBuilder();
- hostBuilder.ConfigureParser(builder =>
- {
- builder.AddCommand("run",
- commandBuilder =>
- {
- commandBuilder.AddOption("opt", "o",
- o => o.Required());
- },
- context =>
- {
- var opt = context.GetOptionValue("opt");
- return Task.FromResult(opt);
- });
- });
- var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(arguments, CancellationToken.None);
- Console.WriteLine("Execution result: {0}", parsingResult);
- }
+ var hostBuilder = new HostBuilder();
+ hostBuilder.ConfigureParser(builder =>
+ {
+ builder.AddCommand("run",
+ commandBuilder =>
+ {
+ commandBuilder.AddOption("opt", "o",
+ o => o.Required());
+ },
+ (context, cancellationToken) =>
+ {
+ var opt = context.GetOptionValue("opt");
+ return Task.FromResult(opt);
+ });
+ });
+ var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(arguments, CancellationToken.None);
+ Console.WriteLine("Execution result: {0}", parsingResult);
}
}
diff --git a/samples/SimpleApp/ParserBuilderCalls.cs b/samples/SimpleApp/ParserBuilderCalls.cs
index 5d1d529..3425f02 100644
--- a/samples/SimpleApp/ParserBuilderCalls.cs
+++ b/samples/SimpleApp/ParserBuilderCalls.cs
@@ -7,93 +7,92 @@
using MGR.CommandLineParser.Tests.Commands;
using Microsoft.Extensions.DependencyInjection;
-namespace SimpleApp
+namespace SimpleApp;
+
+internal static class ParserBuilderCalls
{
- internal static class ParserBuilderCalls
+ internal static async Task CreateAndCallDefaultParserBuilderAsync()
{
- internal static async Task CreateAndCallDefaultParserBuilderAsync()
- {
- Console.WriteLine("ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync");
- var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
+ Console.WriteLine("ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync");
+ var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- var parserBuild = new ParserBuilder(new ParserOptions())
- .AddCommands(builder => builder.AddCommands());
- var parser = parserBuild.BuildParser();
- var commandResult = await parser.Parse(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var parserBuild = new ParserBuilder(new ParserOptions())
+ .AddCommands(builder => builder.AddCommands());
+ var parser = parserBuild.BuildParser();
+ var commandResult = await parser.Parse(arguments);
+ if (commandResult.IsValid)
+ {
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
}
- internal static async Task CreateAndCallCustomizedParserBuilderAsync()
+ else
{
- Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync");
- var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
+ Console.WriteLine("Invalid parsing");
+ }
+ }
+ internal static async Task CreateAndCallCustomizedParserBuilderAsync()
+ {
+ Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync");
+ var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- var serviceCollection = new ServiceCollection();
- var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection)
- .AddCommands(builder => builder.AddCommands());
- var parser = parserBuild.BuildParser();
- var commandResult = await parser.Parse(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var serviceCollection = new ServiceCollection();
+ var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection)
+ .AddCommands(builder => builder.AddCommands());
+ var parser = parserBuild.BuildParser();
+ var commandResult = await parser.Parse(arguments);
+ if (commandResult.IsValid)
+ {
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
}
- internal static async Task CreateAndCallCustomizedWithCommandsParserBuilderAsync()
+ else
{
- Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync");
- var arguments = new[] { "test", "--longName:3", "hello" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
+ Console.WriteLine("Invalid parsing");
+ }
+ }
+ internal static async Task CreateAndCallCustomizedWithCommandsParserBuilderAsync()
+ {
+ Console.WriteLine("ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync");
+ var arguments = new[] { "test", "--longName:3", "hello" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- var serviceCollection = new ServiceCollection();
- serviceCollection.AddCommandLineParser()
- .AddCommand(
- "test",
- commandBuilder =>
- {
- commandBuilder
- .WithDescription("Description of command")
- .AddOption(
- "longName",
- "shortName",
- optionBuilder => {
- optionBuilder.Required()
- .AddValidation(new RangeAttribute(2, 7));
- });
- },
- context =>
- {
- var year = context.GetOptionValue("longName");
- var arg = context.Arguments;
- return Task.FromResult(year + arg.Count());
- });
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddCommandLineParser()
+ .AddCommand(
+ "test",
+ commandBuilder =>
+ {
+ commandBuilder
+ .WithDescription("Description of command")
+ .AddOption(
+ "longName",
+ "shortName",
+ optionBuilder => {
+ optionBuilder.Required()
+ .AddValidation(new RangeAttribute(2, 7));
+ });
+ },
+ (context, cancellationToken) =>
+ {
+ var year = context.GetOptionValue("longName");
+ var arg = context.Arguments;
+ return Task.FromResult(year + arg.Count());
+ });
- var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection)
- .AddCommands(builder => builder.AddCommands());
- var parser = parserBuild.BuildParser();
- var commandResult = await parser.Parse(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection)
+ .AddCommands(builder => builder.AddCommands());
+ var parser = parserBuild.BuildParser();
+ var commandResult = await parser.Parse(arguments);
+ if (commandResult.IsValid)
+ {
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
+ }
+ else
+ {
+ Console.WriteLine("Invalid parsing");
}
}
}
diff --git a/samples/SimpleApp/ParserFactoryCalls.cs b/samples/SimpleApp/ParserFactoryCalls.cs
index d4e5635..d6d1b9d 100644
--- a/samples/SimpleApp/ParserFactoryCalls.cs
+++ b/samples/SimpleApp/ParserFactoryCalls.cs
@@ -4,143 +4,142 @@
using MGR.CommandLineParser.Tests.Commands;
using Microsoft.Extensions.DependencyInjection;
-namespace SimpleApp
+namespace SimpleApp;
+
+internal static class ParserFactoryCalls
{
- internal static class ParserFactoryCalls
+ internal static async Task ConfigureParserAndGetParserFactoryAsync()
{
- internal static async Task ConfigureParserAndGetParserFactoryAsync()
+ Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync");
+ // In Startup class
+ void Configure(IServiceCollection services)
{
- Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync");
- // In Startup class
- void Configure(IServiceCollection services)
- {
- services.AddCommandLineParser(
- options =>
- {
- options.Logo = "Parser via IParserFactory";
- options.CommandLineName = "";
- }
- ).AddCommands();
- }
+ services.AddCommandLineParser(
+ options =>
+ {
+ options.Logo = "Parser via IParserFactory";
+ options.CommandLineName = "";
+ }
+ ).AddCommands();
+ }
+
+ var serviceCollection = new ServiceCollection();
+ Configure(serviceCollection);
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+ using (var serviceScope = serviceProvider.CreateScope())
+ {
+ var scopedServiceProvider = serviceScope.ServiceProvider;
- var serviceCollection = new ServiceCollection();
- Configure(serviceCollection);
- var serviceProvider = serviceCollection.BuildServiceProvider();
- using (var serviceScope = serviceProvider.CreateScope())
+ async Task ActionInController(IParserFactory factory)
{
- var scopedServiceProvider = serviceScope.ServiceProvider;
+ var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- async Task ActionInController(IParserFactory factory)
+ var parser = factory.CreateParser();
+ var commandResult = await parser.Parse(arguments);
+ if (commandResult.IsValid)
{
- var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
-
- var parser = factory.CreateParser();
- var commandResult = await parser.Parse(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
+ }
+ else
+ {
+ Console.WriteLine("Invalid parsing");
}
-
- var parserFactory = scopedServiceProvider.GetRequiredService();
- await ActionInController(parserFactory);
}
+
+ var parserFactory = scopedServiceProvider.GetRequiredService();
+ await ActionInController(parserFactory);
}
+ }
- internal static async Task ConfigureParserAndGetParserFactoryWithSpecificCommandAsync()
+ internal static async Task ConfigureParserAndGetParserFactoryWithSpecificCommandAsync()
+ {
+ Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync");
+ // In Startup class
+ void Configure(IServiceCollection services)
{
- Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync");
- // In Startup class
- void Configure(IServiceCollection services)
- {
- services.AddCommandLineParser(
- options =>
- {
- options.Logo = "Parser via IParserFactory";
- options.CommandLineName = "";
- }
- ).AddCommands();
- }
+ services.AddCommandLineParser(
+ options =>
+ {
+ options.Logo = "Parser via IParserFactory";
+ options.CommandLineName = "";
+ }
+ ).AddCommands();
+ }
- var serviceCollection = new ServiceCollection();
- Configure(serviceCollection);
- var serviceProvider = serviceCollection.BuildServiceProvider();
- using (var serviceScope = serviceProvider.CreateScope())
+ var serviceCollection = new ServiceCollection();
+ Configure(serviceCollection);
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+ using (var serviceScope = serviceProvider.CreateScope())
+ {
+ var scopedServiceProvider = serviceScope.ServiceProvider;
+
+ async Task ActionInController(IParserFactory factory)
{
- var scopedServiceProvider = serviceScope.ServiceProvider;
+ var arguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- async Task ActionInController(IParserFactory factory)
+ var parser = factory.CreateParser();
+ var commandResult = await parser.Parse(arguments);
+ if (commandResult.IsValid)
{
- var arguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
-
- var parser = factory.CreateParser();
- var commandResult = await parser.Parse(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
+ }
+ else
+ {
+ Console.WriteLine("Invalid parsing");
}
-
- var parserFactory = scopedServiceProvider.GetRequiredService();
- await ActionInController(parserFactory);
}
+
+ var parserFactory = scopedServiceProvider.GetRequiredService();
+ await ActionInController(parserFactory);
}
+ }
- internal static async Task ConfigureParserAndGetParserFactoryWithDefaultCommandAsync()
+ internal static async Task ConfigureParserAndGetParserFactoryWithDefaultCommandAsync()
+ {
+ Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync");
+ // In Startup class
+ void Configure(IServiceCollection services)
{
- Console.WriteLine("ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync");
- // In Startup class
- void Configure(IServiceCollection services)
- {
- services.AddCommandLineParser(
- options =>
- {
- options.Logo = "Parser via IParserFactory";
- options.CommandLineName = "";
- }
- ).AddCommands();
- }
+ services.AddCommandLineParser(
+ options =>
+ {
+ options.Logo = "Parser via IParserFactory";
+ options.CommandLineName = "";
+ }
+ ).AddCommands();
+ }
+
+ var serviceCollection = new ServiceCollection();
+ Configure(serviceCollection);
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+ using (var serviceScope = serviceProvider.CreateScope())
+ {
+ var scopedServiceProvider = serviceScope.ServiceProvider;
- var serviceCollection = new ServiceCollection();
- Configure(serviceCollection);
- var serviceProvider = serviceCollection.BuildServiceProvider();
- using (var serviceScope = serviceProvider.CreateScope())
+ async Task ActionInController(IParserFactory factory)
{
- var scopedServiceProvider = serviceScope.ServiceProvider;
+ var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- async Task ActionInController(IParserFactory factory)
+ var parser = factory.CreateParser();
+ var commandResult = await parser.ParseWithDefaultCommand(arguments);
+ if (commandResult.IsValid)
{
- var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
-
- var parser = factory.CreateParser();
- var commandResult = await parser.ParseWithDefaultCommand(arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
+ }
+ else
+ {
+ Console.WriteLine("Invalid parsing");
}
-
- var parserFactory = scopedServiceProvider.GetRequiredService();
- await ActionInController(parserFactory);
}
+
+ var parserFactory = scopedServiceProvider.GetRequiredService();
+ await ActionInController(parserFactory);
}
}
}
diff --git a/samples/SimpleApp/Program.cs b/samples/SimpleApp/Program.cs
index d53ed78..72b7274 100644
--- a/samples/SimpleApp/Program.cs
+++ b/samples/SimpleApp/Program.cs
@@ -6,55 +6,54 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-namespace SimpleApp
+namespace SimpleApp;
+
+internal class Program
{
- internal class Program
+ private static async Task Main(string[] args)
{
- private static async Task Main(string[] args)
- {
- await ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync();
- WriteSeparator();
- await ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync();
- WriteSeparator();
- await ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync();
- WriteSeparator();
-
- await ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync();
- WriteSeparator();
- await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync();
- WriteSeparator();
- await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync();
- WriteSeparator();
+ await ParserBuilderCalls.CreateAndCallDefaultParserBuilderAsync();
+ WriteSeparator();
+ await ParserBuilderCalls.CreateAndCallCustomizedParserBuilderAsync();
+ WriteSeparator();
+ await ParserBuilderCalls.CreateAndCallCustomizedWithCommandsParserBuilderAsync();
+ WriteSeparator();
- await HostBuilderCalls.CreateAndCallDefaultParserBuilderAsync();
- WriteSeparator();
+ await ParserFactoryCalls.ConfigureParserAndGetParserFactoryAsync();
+ WriteSeparator();
+ await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithDefaultCommandAsync();
+ WriteSeparator();
+ await ParserFactoryCalls.ConfigureParserAndGetParserFactoryWithSpecificCommandAsync();
+ WriteSeparator();
- //await Tester.RunSampleTests();
+ await HostBuilderCalls.CreateAndCallDefaultParserBuilderAsync();
+ WriteSeparator();
- var hostBuilder = new HostBuilder();
- hostBuilder.ConfigureParser(builder =>
- {
- builder.AddCommand("run",
- commandBuilder =>
- {
- commandBuilder.AddOption("opt", "o",
- o => o.Required());
- },
- context =>
- {
- var opt = context.GetOptionValue("opt");
- return Task.FromResult(opt);
- });
- });
- var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(args, CancellationToken.None);
- return parsingResult;
- }
+ //await Tester.RunSampleTests();
- static void WriteSeparator()
+ var hostBuilder = new HostBuilder();
+ hostBuilder.ConfigureParser(builder =>
{
- Console.WriteLine();
- Console.WriteLine("-------------");
- Console.WriteLine();
- }
+ builder.AddCommand("run",
+ commandBuilder =>
+ {
+ commandBuilder.AddOption("opt", "o",
+ o => o.Required());
+ },
+ (context, cancellationToken) =>
+ {
+ var opt = context.GetOptionValue("opt");
+ return Task.FromResult(opt);
+ });
+ });
+ var parsingResult = await hostBuilder.ParseCommandLineAndExecuteAsync(args, CancellationToken.None);
+ return parsingResult;
+ }
+
+ static void WriteSeparator()
+ {
+ Console.WriteLine();
+ Console.WriteLine("-------------");
+ Console.WriteLine();
}
}
\ No newline at end of file
diff --git a/samples/SimpleApp/Tester.cs b/samples/SimpleApp/Tester.cs
index f5f5e71..d10eef8 100644
--- a/samples/SimpleApp/Tester.cs
+++ b/samples/SimpleApp/Tester.cs
@@ -10,82 +10,82 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-namespace SimpleApp
+namespace SimpleApp;
+
+internal static class Tester
{
- internal static class Tester
+ public static async Task RunSampleTests()
{
- public static async Task RunSampleTests()
- {
- //Console.ReadLine();
- var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- var defaultPackArguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
- var defaultDeleteArguments = new[] { "delete", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--no-prompt", "--source", "source1" };
- var helpArguments = new[] { "help" };
- var serviceCollection = new ServiceCollection();
- serviceCollection.AddCommandLineParser()
- .AddClassBasedCommands()
- .AddCommand(
- "test",
- commandBuilder =>
- {
- commandBuilder
- .WithDescription("Description of command")
- .AddOption(
- "longName",
- "shortName",
- optionBuilder => {
- optionBuilder.Required()
- .AddValidation(new RangeAttribute(2, 7));
- });
- },
- context =>
- {
- var year = context.GetOptionValue("longName");
- var arg = context.Arguments;
- return Task.FromResult(year + arg.Count());
- });
- serviceCollection.AddLogging(builder => builder
- .SetMinimumLevel(LogLevel.Trace)
- .AddSeq()
- //.AddConsole(options => options.IncludeScopes = true)
- );
- var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection);
- var parser = parserBuild.BuildParser();
- await ParseAndExecute(parser, helpArguments);
+ //Console.ReadLine();
+ var arguments = new[] { "pack", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ var defaultPackArguments = new[] { @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--properties", "Configuration=Release", "--build", "--symbols", "--msbuild-version", "14" };
+ var defaultDeleteArguments = new[] { "delete", @"MGR.CommandLineParser\MGR.CommandLineParser.csproj", "--no-prompt", "--source", "source1" };
+ var helpArguments = new[] { "help" };
+ var serviceCollection = new ServiceCollection();
+ serviceCollection.AddCommandLineParser()
+ .AddClassBasedCommands()
+ .AddCommand(
+ "test",
+ commandBuilder =>
+ {
+ commandBuilder
+ .WithDescription("Description of command")
+ .AddOption(
+ "longName",
+ "shortName",
+ optionBuilder => {
+ optionBuilder.Required()
+ .AddValidation(new RangeAttribute(2, 7));
+ });
+ },
+ (context, cancellationToken) =>
+ {
+ var year = context.GetOptionValue("longName");
+ var arg = context.Arguments;
+ return Task.FromResult(year + arg.Count());
+ });
+ serviceCollection.AddLogging(builder => builder
+ .SetMinimumLevel(LogLevel.Trace)
+ .AddSeq()
+ //.AddConsole(options => options.IncludeScopes = true)
+ );
+ var parserBuild = new ParserBuilder(new ParserOptions(), serviceCollection);
+ var parser = parserBuild.BuildParser();
+ await ParseAndExecute(parser, helpArguments);
- await ParseAndExecute(parser, new[] { "test", "--longName:3", "hello" });
+ await ParseAndExecute(parser, new[] { "test", "--longName:3", "hello" });
- await ParseWithDefaultAndExecute(parser, arguments);
- await ParseWithDefaultAndExecute(parser, defaultPackArguments);
- await ParseWithDefaultAndExecute(parser, defaultDeleteArguments);
+ await ParseWithDefaultAndExecute(parser, arguments);
+ await ParseWithDefaultAndExecute(parser, defaultPackArguments);
+ await ParseWithDefaultAndExecute(parser, defaultDeleteArguments);
- await Task.Delay(TimeSpan.FromSeconds(1));
- }
+ await Task.Delay(TimeSpan.FromSeconds(1));
+ }
- static async Task ParseWithDefaultAndExecute(IParser parser, string[] arguments)
- where TCommand : class, ICommand
- {
- await ParseFuncAndExecute(parser, arguments,
- (p, args) => p.ParseWithDefaultCommand(args));
- }
- static async Task ParseAndExecute(IParser parser, string[] arguments)
+ static async Task ParseWithDefaultAndExecute(IParser parser, string[] arguments)
+ where TCommandHandler : class, ICommandHandler
+ where TCommandData : CommandData, new()
+ {
+ await ParseFuncAndExecute(parser, arguments,
+ (p, args) => p.ParseWithDefaultCommand(args));
+ }
+ static async Task ParseAndExecute(IParser parser, string[] arguments)
+ {
+ await ParseFuncAndExecute(parser, arguments,
+ (p, args) => p.Parse(args));
+ }
+ static async Task ParseFuncAndExecute(IParser parser, string[] arguments, Func, Task> parseFunc)
+ {
+ Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
+ var commandResult = await parseFunc(parser, arguments);
+ if (commandResult.IsValid)
{
- await ParseFuncAndExecute(parser, arguments,
- (p, args) => p.Parse(args));
+ var executionResult = await commandResult.CommandObject!.ExecuteAsync(default);
+ Console.WriteLine("Execution result: {0}", executionResult);
}
- static async Task ParseFuncAndExecute(IParser parser, string[] arguments, Func, Task> parseFunc)
+ else
{
- Console.WriteLine("Parse: '{0}'", string.Join(" ", arguments));
- var commandResult = await parseFunc(parser, arguments);
- if (commandResult.IsValid)
- {
- var executionResult = await commandResult.CommandObject.ExecuteAsync();
- Console.WriteLine("Execution result: {0}", executionResult);
- }
- else
- {
- Console.WriteLine("Invalid parsing");
- }
+ Console.WriteLine("Invalid parsing");
}
}
}
diff --git a/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs b/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs
index 21e002b..a8597de 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/CommandBuilder.cs
@@ -1,96 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+///
+/// Represents the object used to build a lambda-based command.
+///
+public class CommandBuilder
{
+ private readonly string _commandName;
+ private string _description = string.Empty;
+ private string _usage = string.Empty;
+ private readonly List _samples = [];
+ private bool _hideFromHelpListing;
+ private readonly Func> _executeCommand;
+ private readonly List _optionsBuilders = [];
+
+ internal CommandBuilder(string commandName, Func> executeCommand)
+ {
+ _commandName = commandName;
+ _executeCommand = executeCommand;
+ }
+
///
- /// Represents the object used to build a lambda-based command.
+ /// Defines the description of the command.
///
- public class CommandBuilder
+ /// The description of the command.
+ /// The to chain calls.
+ public CommandBuilder WithDescription(string description)
{
- private readonly string _commandName;
- private string _description;
- private string _usage;
- private readonly List _samples = new List();
- private bool _hideFromHelpListing;
- private readonly Func> _executeCommand;
- private readonly List _optionsBuilders = new List();
-
- internal CommandBuilder(string commandName, Func> executeCommand)
- {
- _commandName = commandName;
- _executeCommand = executeCommand;
- }
-
- ///
- /// Defines the description of the command.
- ///
- /// The description of the command.
- /// The to chain calls.
- public CommandBuilder WithDescription(string description)
- {
- _description = description;
- return this;
- }
+ _description = description;
+ return this;
+ }
- ///
- /// Defines the usage of the command.
- ///
- /// The usage of the command.
- /// The to chain calls.
- public CommandBuilder WithUsage(string usage)
- {
- _usage = usage;
- return this;
- }
+ ///
+ /// Defines the usage of the command.
+ ///
+ /// The usage of the command.
+ /// The to chain calls.
+ public CommandBuilder WithUsage(string usage)
+ {
+ _usage = usage;
+ return this;
+ }
- ///
- /// Add a sample to demonstrate the command usage.
- ///
- /// A sample.
- /// The to chain calls.
- public CommandBuilder AddSample(string sample)
- {
- _samples.Add(sample);
- return this;
- }
+ ///
+ /// Add a sample to demonstrate the command usage.
+ ///
+ /// A sample.
+ /// The to chain calls.
+ public CommandBuilder AddSample(string sample)
+ {
+ _samples.Add(sample);
+ return this;
+ }
- ///
- /// Hide the command from the help listing.
- ///
- /// This cannot be undone.
- /// The to chain calls.
- public CommandBuilder HideFromHelpListing()
- {
- _hideFromHelpListing = true;
- return this;
- }
+ ///
+ /// Hide the command from the help listing.
+ ///
+ /// This cannot be undone.
+ /// The to chain calls.
+ public CommandBuilder HideFromHelpListing()
+ {
+ _hideFromHelpListing = true;
+ return this;
+ }
- ///
- /// Add an option to the command.
- ///
- /// The type of the option.
- /// The name of the option.
- /// The short name of the options.
- /// An action to define command
- /// The to chain calls.
- public CommandBuilder AddOption(string optionName, string shortOptionName,
- Action defineOption)
- {
- var optionBuilder = new OptionBuilder(optionName, shortOptionName, typeof(T));
- (defineOption ?? (_ => { }))(optionBuilder);
- _optionsBuilders.Add(optionBuilder);
- return this;
- }
+ ///
+ /// Add an option to the command.
+ ///
+ /// The type of the option.
+ /// The name of the option.
+ /// The short name of the options.
+ /// An action to define command
+ /// The to chain calls.
+ public CommandBuilder AddOption(string optionName, string shortOptionName,
+ Action defineOption)
+ {
+ var optionBuilder = new OptionBuilder(optionName, shortOptionName, typeof(T));
+ (defineOption ?? (_ => { }))(optionBuilder);
+ _optionsBuilders.Add(optionBuilder);
+ return this;
+ }
- internal LambdaBasedCommandType BuildCommandType(IServiceProvider serviceProvider)
- {
- var commandType = new LambdaBasedCommandType(
- new LambdaBasedCommandMetadata(_commandName, _description, _usage, _samples.ToArray(), _hideFromHelpListing),
- _optionsBuilders.Select(builder => builder.ToCommandOption(serviceProvider)).ToList(), _executeCommand);
- return commandType;
- }
+ internal LambdaBasedCommandType BuildCommandType(IServiceProvider serviceProvider)
+ {
+ var commandType = new LambdaBasedCommandType(
+ new LambdaBasedCommandMetadata(_commandName, _description, _usage, _samples.ToArray(), _hideFromHelpListing),
+ _optionsBuilders.Select(builder => builder.ToCommandOption(serviceProvider)).ToList(), _executeCommand);
+ return commandType;
}
}
\ No newline at end of file
diff --git a/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs b/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs
index 8f55b18..a1c9ecc 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/CommandExecutionContext.cs
@@ -2,60 +2,59 @@
using System.Collections.Generic;
using System.Linq;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+///
+/// Represents the context of execution of a lambda-based command.
+///
+public class CommandExecutionContext
{
+ private readonly IEnumerable _commandOptions;
+
+ internal CommandExecutionContext(IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider)
+ {
+ _commandOptions = commandOptions;
+ Arguments = arguments;
+ ServiceProvider = serviceProvider;
+ }
+
///
- /// Represents the context of execution of a lambda-based command.
+ /// Gets the arguments of the command.
///
- public class CommandExecutionContext
+ public IEnumerable Arguments { get; }
+
+ ///
+ /// Gets the value of an option.
+ ///
+ /// The type of the option.
+ /// The name of the option.
+ /// The value of the option.
+ /// If no options are found.
+ /// If the type of the option do not match the specified type.
+ public T? GetOptionValue(string name)
{
- private readonly IEnumerable _commandOptions;
+ var option = _commandOptions.FirstOrDefault(o => o.Metadata.DisplayInfo.Name == name);
+ if (option == null)
+ {
+ throw new ArgumentOutOfRangeException(nameof(name));
+ }
- internal CommandExecutionContext(IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider)
+ if (!typeof(T).IsAssignableFrom(option.OptionType))
{
- _commandOptions = commandOptions;
- Arguments = arguments;
- ServiceProvider = serviceProvider;
+ throw new InvalidOperationException($"The type of the option ({option.OptionType}) do not match the specified type ({typeof(T)})");
}
- ///
- /// Gets the arguments of the command.
- ///
- public IEnumerable Arguments { get; }
-
- ///
- /// Gets the value of an option.
- ///
- /// The type of the option.
- /// The name of the option.
- /// The value of the option.
- /// If no options are found.
- /// If the type of the option do not match the specified type.
- public T GetOptionValue(string name)
+ var rawValue = option.ValueAssigner.GetValue();
+ if (rawValue == null)
{
- var option = _commandOptions.FirstOrDefault(o => o.Metadata.DisplayInfo.Name == name);
- if (option == null)
- {
- throw new ArgumentOutOfRangeException(nameof(name));
- }
-
- if (!typeof(T).IsAssignableFrom(option.OptionType))
- {
- throw new InvalidOperationException($"The type of the option ({option.OptionType}) do not match the specified type ({typeof(T)})");
- }
-
- var rawValue = option.ValueAssigner.GetValue();
- if (rawValue == null)
- {
- return default;
- }
-
- return (T)rawValue;
+ return default;
}
- ///
- /// Gets the current .
- ///
- public IServiceProvider ServiceProvider { get; }
+ return (T)rawValue;
}
+
+ ///
+ /// Gets the current .
+ ///
+ public IServiceProvider ServiceProvider { get; }
}
\ No newline at end of file
diff --git a/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs b/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs
index d35558d..c52d754 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/Extensions/CommandLineParserBuilderLambdaExtensions.cs
@@ -1,35 +1,34 @@
using System;
+using System.Threading;
using System.Threading.Tasks;
using MGR.CommandLineParser.Command.Lambda;
using MGR.CommandLineParser.Extensibility.Command;
-// ReSharper disable once CheckNamespace
-namespace Microsoft.Extensions.DependencyInjection
+namespace Microsoft.Extensions.DependencyInjection;
+
+///
+/// Extension methods for .
+///
+public static class CommandLineParserBuilderLambdaExtensions
{
///
- /// Extension methods for .
+ /// Add a lambda-based command.
///
- public static class CommandLineParserBuilderLambdaExtensions
+ /// The to configure.
+ /// The name of the command.
+ /// An action to define the command.
+ /// A function that represent the execution of the command.
+ /// The so that additional calls can be chained.
+ public static CommandLineParserBuilder AddCommand(this CommandLineParserBuilder builder,
+ string commandName,
+ Action defineCommand,
+ Func> executeCommand)
{
- ///
- /// Add a lambda-based command.
- ///
- /// The to configure.
- /// The name of the command.
- /// An action to define the command.
- /// A function that represent the execution of the command.
- /// The so that additional calls can be chained.
- public static CommandLineParserBuilder AddCommand(this CommandLineParserBuilder builder,
- string commandName,
- Action defineCommand,
- Func> executeCommand)
- {
- var commandBuilder = new CommandBuilder(commandName, executeCommand);
- (defineCommand ?? (_ => {}))(commandBuilder);
+ var commandBuilder = new CommandBuilder(commandName, executeCommand);
+ (defineCommand ?? (_ => {}))(commandBuilder);
- builder.Services.AddScoped(serviceProvider => new LambdaBasedCommandTypeProvider(commandBuilder.BuildCommandType(serviceProvider)));
+ builder.Services.AddScoped(serviceProvider => new LambdaBasedCommandTypeProvider(commandBuilder.BuildCommandType(serviceProvider)));
- return builder;
- }
+ return builder;
}
}
diff --git a/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs
index 17af3de..2d38619 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/ILambdaBasedCommandOptionValueAssigner.cs
@@ -1,8 +1,7 @@
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+internal interface ILambdaBasedCommandOptionValueAssigner
{
- internal interface ILambdaBasedCommandOptionValueAssigner
- {
- object GetValue();
- void AssignValue(object value);
- }
+ object? GetValue();
+ void AssignValue(object value);
}
diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs
index 536c770..3774481 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandMetadata.cs
@@ -1,22 +1,21 @@
using MGR.CommandLineParser.Extensibility.Command;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+internal class LambdaBasedCommandMetadata : ICommandMetadata
{
- internal class LambdaBasedCommandMetadata : ICommandMetadata
+ internal LambdaBasedCommandMetadata(string commandName, string description, string usage, string[] samples, bool hideFromHelpListing)
{
- internal LambdaBasedCommandMetadata(string commandName, string description, string usage, string[] samples, bool hideFromHelpListing)
- {
- Name = commandName;
- Description = description;
- Usage = usage;
- Samples = samples;
- HideFromHelpListing = hideFromHelpListing;
- }
-
- public string Name { get; }
- public string Description { get; }
- public string Usage { get; }
- public string[] Samples { get; }
- public bool HideFromHelpListing { get; }
+ Name = commandName;
+ Description = description;
+ Usage = usage;
+ Samples = samples;
+ HideFromHelpListing = hideFromHelpListing;
}
+
+ public string Name { get; }
+ public string Description { get; }
+ public string Usage { get; }
+ public string[] Samples { get; }
+ public bool HideFromHelpListing { get; }
}
\ No newline at end of file
diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs
index c3455d8..2cc1b97 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObject.cs
@@ -1,28 +1,28 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+internal class LambdaBasedCommandObject: ICommandObject
{
- internal class LambdaBasedCommandObject: ICommandObject
- {
- private readonly Func> _executeCommand;
- private readonly IEnumerable _commandOptions;
- private readonly List _arguments;
- private readonly IServiceProvider _serviceProvider;
+ private readonly Func> _executeCommand;
+ private readonly IEnumerable _commandOptions;
+ private readonly List _arguments;
+ private readonly IServiceProvider _serviceProvider;
- internal LambdaBasedCommandObject(Func> executeCommand, IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider)
- {
- _executeCommand = executeCommand;
- _commandOptions = commandOptions;
- _arguments = arguments;
- _serviceProvider = serviceProvider;
- }
+ internal LambdaBasedCommandObject(Func> executeCommand, IEnumerable commandOptions, List arguments, IServiceProvider serviceProvider)
+ {
+ _executeCommand = executeCommand;
+ _commandOptions = commandOptions;
+ _arguments = arguments;
+ _serviceProvider = serviceProvider;
+ }
- public Task ExecuteAsync()
- {
- var commandContext = new CommandExecutionContext(_commandOptions, _arguments, _serviceProvider);
- return _executeCommand(commandContext);
- }
+ public Task ExecuteAsync(CancellationToken cancellationToken)
+ {
+ var commandContext = new CommandExecutionContext(_commandOptions, _arguments, _serviceProvider);
+ return _executeCommand(commandContext, cancellationToken);
}
}
diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs
index 7a6159d..f1b4289 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandObjectBuilder.cs
@@ -1,47 +1,47 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
+using System.Threading;
using System.Threading.Tasks;
using MGR.CommandLineParser.Extensibility.Command;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+internal class LambdaBasedCommandObjectBuilder : CommandObjectBuilderBase
{
- internal class LambdaBasedCommandObjectBuilder : CommandObjectBuilderBase
- {
- private readonly List _arguments = new List();
- private readonly Func> _executeCommand;
- private readonly IServiceProvider _serviceProvider;
+ private readonly List _arguments = [];
+ private readonly Func> _executeCommand;
+ private readonly IServiceProvider _serviceProvider;
- internal LambdaBasedCommandObjectBuilder(ICommandMetadata commandMetadata,
- IEnumerable commandOptions, IServiceProvider serviceProvider,
- Func> executeCommand)
- : base(commandMetadata, commandOptions)
- {
- _serviceProvider = serviceProvider;
- _executeCommand = executeCommand;
- }
+ internal LambdaBasedCommandObjectBuilder(ICommandMetadata commandMetadata,
+ IEnumerable commandOptions, IServiceProvider serviceProvider,
+ Func> executeCommand)
+ : base(commandMetadata, commandOptions)
+ {
+ _serviceProvider = serviceProvider;
+ _executeCommand = executeCommand;
+ }
- public override void AddArguments(string argument) => _arguments.Add(argument);
+ public override void AddArguments(string argument) => _arguments.Add(argument);
- public override ICommandObject GenerateCommandObject()
- {
- var commandObject = new LambdaBasedCommandObject(_executeCommand, CommandOptions, _arguments, _serviceProvider);
- return commandObject;
- }
+ public override ICommandObject GenerateCommandObject()
+ {
+ var commandObject = new LambdaBasedCommandObject(_executeCommand, CommandOptions, _arguments, _serviceProvider);
+ return commandObject;
+ }
- protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider)
+ protected override bool DoValidate(List validationResults, IServiceProvider serviceProvider)
+ {
+ var isValueValid = true;
+ var instance = new object();
+ foreach (var commandOption in CommandOptions)
{
- var isValueValid = true;
- var instance = new object();
- foreach (var commandOption in CommandOptions)
- {
- var value = commandOption.ValueAssigner.GetValue();
- var validationContext = new ValidationContext(instance, serviceProvider, null) {
- MemberName = commandOption.Metadata.DisplayInfo.Name
- };
- isValueValid &= Validator.TryValidateValue(value, validationContext, validationResults, commandOption.ValidationAttributes);
- }
- return isValueValid;
+ var value = commandOption.ValueAssigner.GetValue();
+ var validationContext = new ValidationContext(instance, serviceProvider, null) {
+ MemberName = commandOption.Metadata.DisplayInfo.Name
+ };
+ isValueValid &= Validator.TryValidateValue(value, validationContext, validationResults, commandOption.ValidationAttributes);
}
+ return isValueValid;
}
}
\ No newline at end of file
diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs
index 6238506..e0722b3 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOption.cs
@@ -5,55 +5,52 @@
using MGR.CommandLineParser.Extensibility.Command;
using MGR.CommandLineParser.Extensibility.Converters;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+[DebuggerDisplay("LambdaOption:{Metadata.DisplayInfo.Name}")]
+internal class LambdaBasedCommandOption : ICommandOption
{
- [DebuggerDisplay("LambdaOption:{Metadata.DisplayInfo.Name}")]
- internal class LambdaBasedCommandOption : ICommandOption
- {
- private readonly IConverter _converter;
+ private readonly IConverter _converter;
- internal LambdaBasedCommandOption(LambdaBasedCommandOptionMetadata commandOptionMetadata, Type optionType, IConverter converter,
- IEnumerable validationAttributes)
+ internal LambdaBasedCommandOption(LambdaBasedCommandOptionMetadata commandOptionMetadata, Type optionType, IConverter converter,
+ IEnumerable validationAttributes)
+ {
+ OptionType = optionType;
+ _converter = converter;
+ Metadata = commandOptionMetadata;
+ ValidationAttributes = validationAttributes;
+ var collectionType = Metadata.CollectionType;
+ switch (collectionType)
{
- OptionType = optionType;
- _converter = converter;
- Metadata = commandOptionMetadata;
- ValidationAttributes = validationAttributes;
- var collectionType = Metadata.CollectionType;
- switch (collectionType)
- {
- case CommandOptionCollectionType.None:
- ValueAssigner = new LambdaBasedCommandOptionSimpleValueAssigner();
- break;
- case CommandOptionCollectionType.Collection:
- ValueAssigner = new LambdaBasedCommandOptionCollectionValueAssigner();
- break;
- case CommandOptionCollectionType.Dictionary:
- ValueAssigner = new LambdaBasedCommandOptionDictionaryValueAssigner();
- break;
- default:
-#pragma warning disable S3928 // Parameter names used into ArgumentException constructors should match an existing one
- throw new ArgumentOutOfRangeException(nameof(collectionType));
-#pragma warning restore S3928 // Parameter names used into ArgumentException constructors should match an existing one
- }
+ case CommandOptionCollectionType.None:
+ ValueAssigner = new LambdaBasedCommandOptionSimpleValueAssigner();
+ break;
+ case CommandOptionCollectionType.Collection:
+ ValueAssigner = new LambdaBasedCommandOptionCollectionValueAssigner();
+ break;
+ case CommandOptionCollectionType.Dictionary:
+ ValueAssigner = new LambdaBasedCommandOptionDictionaryValueAssigner();
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(collectionType));
+ }
- if (!string.IsNullOrEmpty(Metadata.DefaultValue))
- {
- AssignValue(Metadata.DefaultValue);
- }
+ if (!string.IsNullOrEmpty(Metadata.DefaultValue))
+ {
+ AssignValue(Metadata.DefaultValue);
}
+ }
- internal Type OptionType { get; }
- internal ILambdaBasedCommandOptionValueAssigner ValueAssigner { get; }
- internal IEnumerable ValidationAttributes { get; }
+ internal Type OptionType { get; }
+ internal ILambdaBasedCommandOptionValueAssigner ValueAssigner { get; }
+ internal IEnumerable ValidationAttributes { get; }
- public bool ShouldProvideValue => OptionType != typeof(bool);
- public ICommandOptionMetadata Metadata { get; }
+ public bool ShouldProvideValue => OptionType != typeof(bool);
+ public ICommandOptionMetadata Metadata { get; }
- public void AssignValue(string optionValue)
- {
- var value = _converter.Convert(optionValue, OptionType);
- ValueAssigner.AssignValue(value);
- }
+ public void AssignValue(string optionValue)
+ {
+ var value = _converter.Convert(optionValue, OptionType);
+ ValueAssigner.AssignValue(value);
}
}
\ No newline at end of file
diff --git a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs
index 992a68c..1e7dc82 100644
--- a/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs
+++ b/src/MGR.CommandLineParser.Command.Lambda/LambdaBasedCommandOptionCollectionValueAssigner.cs
@@ -2,14 +2,13 @@
using System.Diagnostics;
using System.Linq;
-namespace MGR.CommandLineParser.Command.Lambda
+namespace MGR.CommandLineParser.Command.Lambda;
+
+[DebuggerDisplay("Collection value assigner (currently {Values.Count} values)")]
+internal class LambdaBasedCommandOptionCollectionValueAssigner : ILambdaBasedCommandOptionValueAssigner
{
- [DebuggerDisplay("Collection value assigner (currently {Values.Count} values)")]
- internal class LambdaBasedCommandOptionCollectionValueAssigner : ILambdaBasedCommandOptionValueAssigner
- {
- internal List