Skip to content

Commit 0a63bad

Browse files
petterhjonsequitur
authored andcommitted
fix #2634: Add SetAction for Task<int>
1 parent e68587e commit 0a63bad

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
public System.Void SetAction(System.Func<ParseResult,System.Int32> action)
5656
public System.Void SetAction(System.Func<ParseResult,System.Threading.CancellationToken,System.Threading.Tasks.Task> action)
5757
public System.Void SetAction(System.Func<ParseResult,System.Threading.Tasks.Task> action)
58+
public System.Void SetAction(System.Func<ParseResult,System.Threading.Tasks.Task<System.Int32>> action)
5859
public System.Void SetAction(System.Func<ParseResult,System.Threading.CancellationToken,System.Threading.Tasks.Task<System.Int32>> action)
5960
public static class CompletionSourceExtensions
6061
public static System.Void Add(this System.Collections.Generic.List<System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem>>> completionSources, System.Func<System.CommandLine.Completions.CompletionContext,System.Collections.Generic.IEnumerable<System.String>> completionsDelegate)

src/System.CommandLine.Tests/Invocation/InvocationTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ public async Task Anonymous_RootCommand_Task_returning_Action_can_set_custom_res
160160
(await rootCommand.Parse("").InvokeAsync()).Should().Be(123);
161161
}
162162

163+
[Fact]
164+
public async Task Anonymous_RootCommand_Task_int_returning_Action_can_set_custom_result_code_via_InvokeAsync()
165+
{
166+
var rootCommand = new RootCommand();
167+
168+
rootCommand.SetAction(_ => Task.FromResult(123));
169+
170+
(await rootCommand.Parse("").InvokeAsync()).Should().Be(123);
171+
}
172+
163173
[Fact]
164174
public void Anonymous_RootCommand_int_returning_Action_can_set_custom_result_code_via_Invoke()
165175
{

src/System.CommandLine/Command.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,36 @@ public void SetAction(Func<ParseResult, Task> action)
166166
throw new ArgumentNullException(nameof(action));
167167
}
168168

169-
Action = new AnonymousAsynchronousCommandLineAction(async (context, cancellationToken) =>
169+
Action = new AnonymousAsynchronousCommandLineAction(async (context, _) =>
170170
{
171171
await action(context);
172172
return 0;
173173
});
174174
}
175175

176+
/// <summary>
177+
/// Sets an asynchronous action to be run when the command is invoked.
178+
/// </summary>
179+
/// <remarks>
180+
/// When possible, prefer using the <see cref="SetAction(Func{ParseResult, CancellationToken, Task{int}})"/> overload
181+
/// and passing the <see cref="CancellationToken"/> parameter to the async method(s) called by the action.
182+
/// </remarks>
183+
// Hide from intellisense, it's public to avoid the compiler choosing a sync overload
184+
// for an async action (and fire and forget issue described in https://github.com/dotnet/command-line-api/issues/2562).
185+
[EditorBrowsable(EditorBrowsableState.Never)]
186+
public void SetAction(Func<ParseResult, Task<int>> action)
187+
{
188+
if (action is null)
189+
{
190+
throw new ArgumentNullException(nameof(action));
191+
}
192+
193+
Action = new AnonymousAsynchronousCommandLineAction(async (context, _) =>
194+
{
195+
return await action(context);
196+
});
197+
}
198+
176199
/// <summary>
177200
/// Sets an asynchronous action when the command is invoked.
178201
/// </summary>

0 commit comments

Comments
 (0)