@@ -10,38 +10,49 @@ internal static class InvocationPipeline
1010 {
1111 internal static async Task < int > InvokeAsync ( ParseResult parseResult , CancellationToken cancellationToken )
1212 {
13- if ( parseResult . Action is null )
14- {
15- return ReturnCodeForMissingAction ( parseResult ) ;
16- }
17-
1813 ProcessTerminationHandler ? terminationHandler = null ;
1914 using CancellationTokenSource cts = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
2015
2116 try
2217 {
18+ int actionResult = 0 ;
19+ int preActionResult = 0 ;
20+
2321 if ( parseResult . PreActions is not null )
2422 {
2523 for ( int i = 0 ; i < parseResult . PreActions . Count ; i ++ )
2624 {
2725 var action = parseResult . PreActions [ i ] ;
26+ var result = 0 ;
2827
2928 switch ( action )
3029 {
3130 case SynchronousCommandLineAction syncAction :
32- syncAction . Invoke ( parseResult ) ;
31+ result = syncAction . Invoke ( parseResult ) ;
3332 break ;
3433 case AsynchronousCommandLineAction asyncAction :
35- await asyncAction . InvokeAsync ( parseResult , cts . Token ) ;
34+ result = await asyncAction . InvokeAsync ( parseResult , cts . Token ) ;
3635 break ;
36+
37+ }
38+
39+ if ( result != 0 )
40+ {
41+ preActionResult = result ;
3742 }
3843 }
3944 }
4045
46+ if ( parseResult . Action is null )
47+ {
48+ return preActionResult != 0 ? preActionResult : ReturnCodeForMissingAction ( parseResult ) ;
49+ }
50+
4151 switch ( parseResult . Action )
4252 {
4353 case SynchronousCommandLineAction syncAction :
44- return syncAction . Invoke ( parseResult ) ;
54+ actionResult = syncAction . Invoke ( parseResult ) ;
55+ break ;
4556
4657 case AsynchronousCommandLineAction asyncAction :
4758 var timeout = parseResult . InvocationConfiguration . ProcessTerminationTimeout ;
@@ -55,7 +66,7 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
5566
5667 if ( terminationHandler is null )
5768 {
58- return await startedInvocation ;
69+ actionResult = await startedInvocation ;
5970 }
6071 else
6172 {
@@ -64,12 +75,15 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
6475 // In such cases, when CancelOnProcessTermination is configured and user presses Ctrl+C,
6576 // ProcessTerminationCompletionSource completes first, with the result equal to native exit code for given signal.
6677 Task < int > firstCompletedTask = await Task . WhenAny ( startedInvocation , terminationHandler . ProcessTerminationCompletionSource . Task ) ;
67- return await firstCompletedTask ; // return the result or propagate the exception
78+ actionResult = await firstCompletedTask ; // return the result or propagate the exception
6879 }
80+ break ;
6981
7082 default :
7183 throw new ArgumentOutOfRangeException ( nameof ( parseResult . Action ) ) ;
7284 }
85+
86+ return preActionResult != 0 ? preActionResult : actionResult ;
7387 }
7488 catch ( Exception ex ) when ( parseResult . InvocationConfiguration . EnableDefaultExceptionHandler )
7589 {
@@ -83,48 +97,42 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
8397
8498 internal static int Invoke ( ParseResult parseResult )
8599 {
86- switch ( parseResult . Action )
100+ try
87101 {
88- case null :
89- return ReturnCodeForMissingAction ( parseResult ) ;
102+ int preActionResult = 0 ;
90103
91- case SynchronousCommandLineAction syncAction :
92- try
104+ if ( parseResult . PreActions is not null )
105+ {
106+ for ( var i = 0 ; i < parseResult . PreActions . Count ; i ++ )
93107 {
94- if ( parseResult . PreActions is not null )
108+ if ( parseResult . PreActions [ i ] is SynchronousCommandLineAction syncPreAction )
95109 {
96- #if DEBUG
97- for ( var i = 0 ; i < parseResult . PreActions . Count ; i ++ )
98- {
99- var action = parseResult . PreActions [ i ] ;
100-
101- if ( action is not SynchronousCommandLineAction )
102- {
103- parseResult . InvocationConfiguration . EnableDefaultExceptionHandler = false ;
104- throw new Exception (
105- $ "This should not happen. An instance of { nameof ( AsynchronousCommandLineAction ) } ({ action } ) was called within { nameof ( InvocationPipeline ) } .{ nameof ( Invoke ) } . This is supposed to be detected earlier resulting in a call to { nameof ( InvocationPipeline ) } { nameof ( InvokeAsync ) } ") ;
106- }
107- }
108- #endif
109-
110- for ( var i = 0 ; i < parseResult . PreActions . Count ; i ++ )
110+ int result = syncPreAction . Invoke ( parseResult ) ;
111+
112+ if ( result != 0 )
111113 {
112- if ( parseResult . PreActions [ i ] is SynchronousCommandLineAction syncPreAction )
113- {
114- syncPreAction . Invoke ( parseResult ) ;
115- }
114+ preActionResult = result ;
116115 }
117116 }
118-
119- return syncAction . Invoke ( parseResult ) ;
120- }
121- catch ( Exception ex ) when ( parseResult . InvocationConfiguration . EnableDefaultExceptionHandler )
122- {
123- return DefaultExceptionHandler ( ex , parseResult ) ;
124117 }
118+ }
119+
120+ switch ( parseResult . Action )
121+ {
122+ case null :
123+ return preActionResult != 0 ? preActionResult : ReturnCodeForMissingAction ( parseResult ) ;
125124
126- default :
127- throw new InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) } called within non-async invocation.") ;
125+ case SynchronousCommandLineAction syncAction :
126+ int actionResult = syncAction . Invoke ( parseResult ) ;
127+ return preActionResult != 0 ? preActionResult : actionResult ;
128+
129+ default :
130+ throw new InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) } called within non-async invocation.") ;
131+ }
132+ }
133+ catch ( Exception ex ) when ( parseResult . InvocationConfiguration . EnableDefaultExceptionHandler )
134+ {
135+ return DefaultExceptionHandler ( ex , parseResult ) ;
128136 }
129137 }
130138
0 commit comments