mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Use ValueTask
This commit is contained in:
2
.github/workflows/CD.yml
vendored
2
.github/workflows/CD.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- name: Install .NET Core
|
- name: Install .NET Core
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.0.100
|
dotnet-version: 3.1.100
|
||||||
|
|
||||||
- name: Pack
|
- name: Pack
|
||||||
run: dotnet pack CliFx --configuration Release
|
run: dotnet pack CliFx --configuration Release
|
||||||
|
|||||||
2
.github/workflows/CI.yml
vendored
2
.github/workflows/CI.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
- name: Install .NET Core
|
- name: Install .NET Core
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v1
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.0.100
|
dotnet-version: 3.1.100
|
||||||
|
|
||||||
- name: Build & test
|
- name: Build & test
|
||||||
run: dotnet test --configuration Release
|
run: dotnet test --configuration Release
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ using CliFx.Benchmarks.Commands;
|
|||||||
|
|
||||||
namespace CliFx.Benchmarks
|
namespace CliFx.Benchmarks
|
||||||
{
|
{
|
||||||
[CoreJob]
|
[SimpleJob]
|
||||||
[RankColumn]
|
[RankColumn]
|
||||||
public class Benchmark
|
public class Benchmark
|
||||||
{
|
{
|
||||||
private static readonly string[] Arguments = {"--str", "hello world", "-i", "13", "-b"};
|
private static readonly string[] Arguments = {"--str", "hello world", "-i", "13", "-b"};
|
||||||
|
|
||||||
[Benchmark(Description = "CliFx", Baseline = true)]
|
[Benchmark(Description = "CliFx", Baseline = true)]
|
||||||
public Task<int> ExecuteWithCliFx() => new CliApplicationBuilder().AddCommand(typeof(CliFxCommand)).Build().RunAsync(Arguments);
|
public async ValueTask<int> ExecuteWithCliFx() => await new CliApplicationBuilder().AddCommand(typeof(CliFxCommand)).Build().RunAsync(Arguments);
|
||||||
|
|
||||||
[Benchmark(Description = "System.CommandLine")]
|
[Benchmark(Description = "System.CommandLine")]
|
||||||
public Task<int> ExecuteWithSystemCommandLine() => new SystemCommandLineCommand().ExecuteAsync(Arguments);
|
public async ValueTask<int> ExecuteWithSystemCommandLine() => await new SystemCommandLineCommand().ExecuteAsync(Arguments);
|
||||||
|
|
||||||
[Benchmark(Description = "McMaster.Extensions.CommandLineUtils")]
|
[Benchmark(Description = "McMaster.Extensions.CommandLineUtils")]
|
||||||
public int ExecuteWithMcMaster() => McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute<McMasterCommand>(Arguments);
|
public int ExecuteWithMcMaster() => McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute<McMasterCommand>(Arguments);
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.11.5" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
|
||||||
<PackageReference Include="clipr" Version="1.6.1" />
|
<PackageReference Include="clipr" Version="1.6.1" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.6.0" />
|
<PackageReference Include="CommandLineParser" Version="2.6.0" />
|
||||||
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.3.4" />
|
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.4.4" />
|
||||||
<PackageReference Include="PowerArgs" Version="3.6.0" />
|
<PackageReference Include="PowerArgs" Version="3.6.0" />
|
||||||
<PackageReference Include="System.CommandLine.Experimental" Version="0.3.0-alpha.19317.1" />
|
<PackageReference Include="System.CommandLine.Experimental" Version="0.3.0-alpha.19317.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ namespace CliFx.Benchmarks.Commands
|
|||||||
[CommandOption("bool", 'b')]
|
[CommandOption("bool", 'b')]
|
||||||
public bool BoolOption { get; set; }
|
public bool BoolOption { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace CliFx.Demo.Commands
|
|||||||
_libraryService = libraryService;
|
_libraryService = libraryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
// To make the demo simpler, we will just generate random publish date and ISBN if they were not set
|
// To make the demo simpler, we will just generate random publish date and ISBN if they were not set
|
||||||
if (Published == default)
|
if (Published == default)
|
||||||
@@ -48,7 +48,7 @@ namespace CliFx.Demo.Commands
|
|||||||
console.Output.WriteLine("Book added.");
|
console.Output.WriteLine("Book added.");
|
||||||
console.RenderBook(book);
|
console.RenderBook(book);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace CliFx.Demo.Commands
|
|||||||
_libraryService = libraryService;
|
_libraryService = libraryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
var book = _libraryService.GetBook(Title);
|
var book = _libraryService.GetBook(Title);
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ namespace CliFx.Demo.Commands
|
|||||||
|
|
||||||
console.RenderBook(book);
|
console.RenderBook(book);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ namespace CliFx.Demo.Commands
|
|||||||
_libraryService = libraryService;
|
_libraryService = libraryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
var library = _libraryService.GetLibrary();
|
var library = _libraryService.GetLibrary();
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ namespace CliFx.Demo.Commands
|
|||||||
console.RenderBook(book);
|
console.RenderBook(book);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ namespace CliFx.Demo.Commands
|
|||||||
_libraryService = libraryService;
|
_libraryService = libraryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
var book = _libraryService.GetBook(Title);
|
var book = _libraryService.GetBook(Title);
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ namespace CliFx.Demo.Commands
|
|||||||
|
|
||||||
console.Output.WriteLine($"Book {Title} removed.");
|
console.Output.WriteLine($"Book {Title} removed.");
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,11 +25,11 @@ namespace CliFx.Demo
|
|||||||
return services.BuildServiceProvider();
|
return services.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<int> Main(string[] args)
|
public static async Task<int> Main(string[] args)
|
||||||
{
|
{
|
||||||
var serviceProvider = ConfigureServices();
|
var serviceProvider = ConfigureServices();
|
||||||
|
|
||||||
return new CliApplicationBuilder()
|
return await new CliApplicationBuilder()
|
||||||
.AddCommandsFromThisAssembly()
|
.AddCommandsFromThisAssembly()
|
||||||
.UseCommandFactory(schema => (ICommand) serviceProvider.GetRequiredService(schema.Type))
|
.UseCommandFactory(schema => (ICommand) serviceProvider.GetRequiredService(schema.Type))
|
||||||
.Build()
|
.Build()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<Import Project="../CliFx.props" />
|
<Import Project="../CliFx.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
<IsTestProject>true</IsTestProject>
|
<IsTestProject>true</IsTestProject>
|
||||||
<CollectCoverage>true</CollectCoverage>
|
<CollectCoverage>true</CollectCoverage>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[Command("cancel")]
|
[Command("cancel")]
|
||||||
public class CancellableCommand : ICommand
|
public class CancellableCommand : ICommand
|
||||||
{
|
{
|
||||||
public async Task ExecuteAsync(IConsole console)
|
public async ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("msg", 'm')]
|
[CommandOption("msg", 'm')]
|
||||||
public string? Message { get; set; }
|
public string? Message { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => throw new CommandException(Message, ExitCode);
|
public ValueTask ExecuteAsync(IConsole console) => throw new CommandException(Message, ExitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,10 +14,10 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption('s', Description = "String separator.")]
|
[CommandOption('s', Description = "String separator.")]
|
||||||
public string Separator { get; set; } = "";
|
public string Separator { get; set; } = "";
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
console.Output.WriteLine(string.Join(Separator, Inputs));
|
console.Output.WriteLine(string.Join(Separator, Inputs));
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,10 +16,10 @@ namespace CliFx.Tests.TestCommands
|
|||||||
// This property should be ignored by resolver
|
// This property should be ignored by resolver
|
||||||
public bool NotAnOption { get; set; }
|
public bool NotAnOption { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
console.Output.WriteLine(Dividend / Divisor);
|
console.Output.WriteLine(Dividend / Divisor);
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("fruits")]
|
[CommandOption("fruits")]
|
||||||
public string? Oranges { get; set; }
|
public string? Oranges { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption('f')]
|
[CommandOption('f')]
|
||||||
public string? Oranges { get; set; }
|
public string? Oranges { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("opt", EnvironmentVariableName = "ENV_SINGLE_VALUE")]
|
[CommandOption("opt", EnvironmentVariableName = "ENV_SINGLE_VALUE")]
|
||||||
public string? Option { get; set; }
|
public string? Option { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
|
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
|
||||||
public IEnumerable<string>? Option { get; set; }
|
public IEnumerable<string>? Option { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
|
[CommandOption("opt", EnvironmentVariableName = "ENV_MULTIPLE_VALUES")]
|
||||||
public string? Option { get; set; }
|
public string? Option { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("msg", 'm')]
|
[CommandOption("msg", 'm')]
|
||||||
public string? Message { get; set; }
|
public string? Message { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => throw new Exception(Message);
|
public ValueTask ExecuteAsync(IConsole console) => throw new Exception(Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,10 +7,10 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[Command]
|
[Command]
|
||||||
public class HelloWorldDefaultCommand : ICommand
|
public class HelloWorldDefaultCommand : ICommand
|
||||||
{
|
{
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
console.Output.WriteLine("Hello world.");
|
console.Output.WriteLine("Hello world.");
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("option-b", 'b', Description = "OptionB description.")]
|
[CommandOption("option-b", 'b', Description = "OptionB description.")]
|
||||||
public string? OptionB { get; set; }
|
public string? OptionB { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("option-d", 'd', Description = "OptionD description.")]
|
[CommandOption("option-d", 'd', Description = "OptionD description.")]
|
||||||
public string? OptionD { get; set; }
|
public string? OptionD { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
[CommandOption("option-e", 'e', Description = "OptionE description.")]
|
[CommandOption("option-e", 'e', Description = "OptionE description.")]
|
||||||
public string? OptionE { get; set; }
|
public string? OptionE { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,6 @@ namespace CliFx.Tests.TestCommands
|
|||||||
{
|
{
|
||||||
public class NonAnnotatedCommand : ICommand
|
public class NonAnnotatedCommand : ICommand
|
||||||
{
|
{
|
||||||
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
|
public ValueTask ExecuteAsync(IConsole console) => default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ namespace CliFx
|
|||||||
_helpTextRenderer = helpTextRenderer;
|
_helpTextRenderer = helpTextRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int?> HandleDebugDirectiveAsync(CommandInput commandInput)
|
private async ValueTask<int?> HandleDebugDirectiveAsync(CommandInput commandInput)
|
||||||
{
|
{
|
||||||
// Debug mode is enabled if it's allowed in the application and it was requested via corresponding directive
|
// Debug mode is enabled if it's allowed in the application and it was requested via corresponding directive
|
||||||
var isDebugMode = _configuration.IsDebugModeAllowed && commandInput.IsDebugDirectiveSpecified();
|
var isDebugMode = _configuration.IsDebugModeAllowed && commandInput.IsDebugDirectiveSpecified();
|
||||||
@@ -162,7 +162,7 @@ namespace CliFx
|
|||||||
return isError ? -1 : 0;
|
return isError ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> HandleCommandExecutionAsync(CommandInput commandInput, CommandSchema targetCommandSchema)
|
private async ValueTask<int> HandleCommandExecutionAsync(CommandInput commandInput, CommandSchema targetCommandSchema)
|
||||||
{
|
{
|
||||||
// Create an instance of the command
|
// Create an instance of the command
|
||||||
var command = _commandFactory.CreateCommand(targetCommandSchema);
|
var command = _commandFactory.CreateCommand(targetCommandSchema);
|
||||||
@@ -178,7 +178,7 @@ namespace CliFx
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<int> RunAsync(IReadOnlyList<string> commandLineArguments)
|
public async ValueTask<int> RunAsync(IReadOnlyList<string> commandLineArguments)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<Import Project="../CliFx.props" />
|
<Import Project="../CliFx.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net45;netstandard2.0;netstandard2.1</TargetFrameworks>
|
<TargetFrameworks>netstandard2.1;netstandard2.0;net45</TargetFrameworks>
|
||||||
<Authors>$(Company)</Authors>
|
<Authors>$(Company)</Authors>
|
||||||
<Description>Declarative framework for CLI applications</Description>
|
<Description>Declarative framework for CLI applications</Description>
|
||||||
<PackageTags>command line executable interface framework parser arguments net core</PackageTags>
|
<PackageTags>command line executable interface framework parser arguments net core</PackageTags>
|
||||||
@@ -18,15 +18,18 @@
|
|||||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0-preview.2" PrivateAssets="all" />
|
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-19554-01" PrivateAssets="all" />
|
|
||||||
<PackageReference Include="Nullable" Version="1.1.1" PrivateAssets="all" />
|
|
||||||
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="../favicon.png" Pack="True" PackagePath="" />
|
<None Include="../favicon.png" Pack="True" PackagePath="" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="all" />
|
||||||
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
|
||||||
|
<PackageReference Include="Nullable" Version="1.1.1" PrivateAssets="all" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'net45'">
|
||||||
|
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -11,6 +11,6 @@ namespace CliFx
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs application with specified command line arguments and returns an exit code.
|
/// Runs application with specified command line arguments and returns an exit code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task<int> RunAsync(IReadOnlyList<string> commandLineArguments);
|
ValueTask<int> RunAsync(IReadOnlyList<string> commandLineArguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,6 @@ namespace CliFx
|
|||||||
/// Executes command using specified implementation of <see cref="IConsole"/>.
|
/// Executes command using specified implementation of <see cref="IConsole"/>.
|
||||||
/// This method is called when the command is invoked by a user through command line interface.
|
/// This method is called when the command is invoked by a user through command line interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Task ExecuteAsync(IConsole console);
|
ValueTask ExecuteAsync(IConsole console);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
26
Readme.md
26
Readme.md
@@ -59,8 +59,8 @@ The following code will create and run default `CliApplication` that will resolv
|
|||||||
```c#
|
```c#
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static Task<int> Main(string[] args) =>
|
public static async Task<int> Main(string[] args) =>
|
||||||
new CliApplicationBuilder()
|
await new CliApplicationBuilder()
|
||||||
.AddCommandsFromThisAssembly()
|
.AddCommandsFromThisAssembly()
|
||||||
.Build()
|
.Build()
|
||||||
.RunAsync(args);
|
.RunAsync(args);
|
||||||
@@ -85,17 +85,17 @@ public class LogCommand : ICommand
|
|||||||
[CommandOption("base", 'b', Description = "Logarithm base.")]
|
[CommandOption("base", 'b', Description = "Logarithm base.")]
|
||||||
public double Base { get; set; } = 10;
|
public double Base { get; set; } = 10;
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
var result = Math.Log(Value, Base);
|
var result = Math.Log(Value, Base);
|
||||||
console.Output.WriteLine(result);
|
console.Output.WriteLine(result);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
By implementing `ICommand` this class also provides `ExecuteAsync` method. This is the method that gets called when the user invokes the command. Its return type is `Task` in order to facilitate asynchronous execution, but if your command runs synchronously you can simply return `Task.CompletedTask`.
|
By implementing `ICommand` this class also provides `ExecuteAsync` method. This is the method that gets called when the user invokes the command. Its return type is `ValueTask` in order to facilitate both synchronous and asynchronous execution. If your command always runs synchronously, simply return `default` at the end of the method.
|
||||||
|
|
||||||
The `ExecuteAsync` method also takes an instance of `IConsole` as a parameter. You should use the `console` parameter in places where you would normally use `System.Console`, in order to make your command testable.
|
The `ExecuteAsync` method also takes an instance of `IConsole` as a parameter. You should use the `console` parameter in places where you would normally use `System.Console`, in order to make your command testable.
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ public class DivideCommand : ICommand
|
|||||||
[CommandOption("divisor", IsRequired = true)]
|
[CommandOption("divisor", IsRequired = true)]
|
||||||
public double Divisor { get; set; }
|
public double Divisor { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
if (Math.Abs(Divisor) < double.Epsilon)
|
if (Math.Abs(Divisor) < double.Epsilon)
|
||||||
{
|
{
|
||||||
@@ -182,7 +182,7 @@ public class DivideCommand : ICommand
|
|||||||
var result = Dividend / Divisor;
|
var result = Dividend / Divisor;
|
||||||
console.Output.WriteLine(result);
|
console.Output.WriteLine(result);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -225,7 +225,7 @@ Cancelled or terminated app returns non-zero exit code.
|
|||||||
[Command("cancel")]
|
[Command("cancel")]
|
||||||
public class CancellableCommand : ICommand
|
public class CancellableCommand : ICommand
|
||||||
{
|
{
|
||||||
public async Task ExecuteAsync(IConsole console)
|
public async ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
console.Output.WriteLine("Printed");
|
console.Output.WriteLine("Printed");
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ For example, here is how you would configure your application to use [`Microsoft
|
|||||||
```c#
|
```c#
|
||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
public static Task<int> Main(string[] args)
|
public static async Task<int> Main(string[] args)
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ public static class Program
|
|||||||
|
|
||||||
var serviceProvider = services.BuildServiceProvider();
|
var serviceProvider = services.BuildServiceProvider();
|
||||||
|
|
||||||
return new CliApplicationBuilder()
|
return await new CliApplicationBuilder()
|
||||||
.AddCommandsFromThisAssembly()
|
.AddCommandsFromThisAssembly()
|
||||||
.UseCommandFactory(schema => (ICommand) serviceProvider.GetRequiredService(schema.Type))
|
.UseCommandFactory(schema => (ICommand) serviceProvider.GetRequiredService(schema.Type))
|
||||||
.Build()
|
.Build()
|
||||||
@@ -285,7 +285,7 @@ public class UserAddCommand : ICommand
|
|||||||
[CommandOption("email", 'e')]
|
[CommandOption("email", 'e')]
|
||||||
public string Email { get; set; }
|
public string Email { get; set; }
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
var validationResult = new UserAddCommandValidator().Validate(this);
|
var validationResult = new UserAddCommandValidator().Validate(this);
|
||||||
if (!validationResult.IsValid)
|
if (!validationResult.IsValid)
|
||||||
@@ -358,13 +358,13 @@ public class ConcatCommand : ICommand
|
|||||||
[CommandOption("right")]
|
[CommandOption("right")]
|
||||||
public string Right { get; set; } = "world";
|
public string Right { get; set; } = "world";
|
||||||
|
|
||||||
public Task ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
console.Output.Write(Left);
|
console.Output.Write(Left);
|
||||||
console.Output.Write(' ');
|
console.Output.Write(' ');
|
||||||
console.Output.Write(Right);
|
console.Output.Write(Right);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user