11// Copyright (c) .NET Foundation and contributors. All rights reserved. 
22// Licensed under the MIT license. See LICENSE file in the project root for full license information. 
33
4+ using  System . Runtime . CompilerServices ; 
45using  System . Threading ; 
56using  System . Threading . Tasks ; 
67
@@ -10,8 +11,16 @@ internal static class InvocationPipeline
1011    { 
1112        internal  static   async  Task < int >  InvokeAsync ( ParseResult  parseResult ,  CancellationToken  cancellationToken ) 
1213        { 
14+             using  var  invokeActivity  =  Activities . ActivitySource . StartActivity ( DiagnosticsStrings . InvokeMethod ) ; 
15+             if  ( invokeActivity  is  not null ) 
16+             { 
17+                 invokeActivity . DisplayName  =  parseResult . CommandResult . FullCommandName ( ) ; 
18+                 invokeActivity . AddTag ( DiagnosticsStrings . Command ,  parseResult . CommandResult . Command . Name ) ; 
19+             } 
20+ 
1321            if  ( parseResult . Action  is  null ) 
1422            { 
23+                 invokeActivity ? . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ; 
1524                return  ReturnCodeForMissingAction ( parseResult ) ; 
1625            } 
1726
@@ -41,7 +50,9 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
4150                switch  ( parseResult . Action ) 
4251                { 
4352                    case  SynchronousCommandLineAction  syncAction : 
44-                         return  syncAction . Invoke ( parseResult ) ; 
53+                         var  syncResult  =  syncAction . Invoke ( parseResult ) ; 
54+                         invokeActivity ? . SetExitCode ( syncResult ) ; 
55+                         return  syncResult ; 
4556
4657                    case  AsynchronousCommandLineAction  asyncAction : 
4758                        var  startedInvocation  =  asyncAction . InvokeAsync ( parseResult ,  cts . Token ) ; 
@@ -52,23 +63,30 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
5263
5364                        if  ( terminationHandler  is  null ) 
5465                        { 
55-                             return  await  startedInvocation ; 
66+                             var  asyncResult  =  await  startedInvocation ; 
67+                             invokeActivity ? . SetExitCode ( asyncResult ) ; 
68+                             return  asyncResult ; 
5669                        } 
5770                        else 
5871                        { 
5972                            // Handlers may not implement cancellation. 
6073                            // In such cases, when CancelOnProcessTermination is configured and user presses Ctrl+C, 
6174                            // ProcessTerminationCompletionSource completes first, with the result equal to native exit code for given signal. 
6275                            Task < int >  firstCompletedTask  =  await  Task . WhenAny ( startedInvocation ,  terminationHandler . ProcessTerminationCompletionSource . Task ) ; 
63-                             return  await  firstCompletedTask ;  // return the result or propagate the exception 
76+                             var  asyncResult  =  await  firstCompletedTask ;   // return the result or propagate the exception 
77+                             invokeActivity ? . SetExitCode ( asyncResult ) ; 
78+                             return  asyncResult ; 
6479                        } 
6580
6681                    default : 
67-                         throw  new  ArgumentOutOfRangeException ( nameof ( parseResult . Action ) ) ; 
82+                         var  error  =  new  ArgumentOutOfRangeException ( nameof ( parseResult . Action ) ) ; 
83+                         invokeActivity ? . Error ( error ) ; 
84+                         throw  error ; 
6885                } 
6986            } 
7087            catch  ( Exception  ex )  when  ( parseResult . Configuration . EnableDefaultExceptionHandler ) 
7188            { 
89+                 invokeActivity ? . Error ( ex ) ; 
7290                return  DefaultExceptionHandler ( ex ,  parseResult . Configuration ) ; 
7391            } 
7492            finally 
@@ -79,9 +97,17 @@ internal static async Task<int> InvokeAsync(ParseResult parseResult, Cancellatio
7997
8098        internal  static   int  Invoke ( ParseResult  parseResult ) 
8199        { 
100+             using  var  invokeActivity  =  Activities . ActivitySource . StartActivity ( DiagnosticsStrings . InvokeMethod ) ; 
101+             if  ( invokeActivity  is  not null ) 
102+             { 
103+                 invokeActivity . DisplayName  =  parseResult . CommandResult . FullCommandName ( ) ; 
104+                 invokeActivity . AddTag ( DiagnosticsStrings . Command ,  parseResult . CommandResult . Command . Name ) ; 
105+             } 
106+ 
82107            switch  ( parseResult . Action ) 
83108            { 
84109                case  null : 
110+                     invokeActivity ? . Error ( ) ; 
85111                    return  ReturnCodeForMissingAction ( parseResult ) ; 
86112
87113                case  SynchronousCommandLineAction  syncAction : 
@@ -112,15 +138,20 @@ internal static int Invoke(ParseResult parseResult)
112138                            } 
113139                        } 
114140
115-                         return  syncAction . Invoke ( parseResult ) ; 
141+                         var  result  =  syncAction . Invoke ( parseResult ) ; 
142+                         invokeActivity ? . SetExitCode ( result ) ; 
143+                         return  result ; 
116144                    } 
117145                    catch  ( Exception  ex )  when  ( parseResult . Configuration . EnableDefaultExceptionHandler ) 
118146                    { 
147+                         invokeActivity ? . Error ( ex ) ; 
119148                        return  DefaultExceptionHandler ( ex ,  parseResult . Configuration ) ; 
120149                    } 
121150
122151                default : 
123-                     throw  new  InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) }  called within non-async invocation.") ; 
152+                     var  error  =  new  InvalidOperationException ( $ "{ nameof ( AsynchronousCommandLineAction ) }  called within non-async invocation.") ; 
153+                     invokeActivity ? . Error ( error ) ; 
154+                     throw  error ; 
124155            } 
125156        } 
126157
@@ -150,5 +181,38 @@ private static int ReturnCodeForMissingAction(ParseResult parseResult)
150181                return  0 ; 
151182            } 
152183        } 
184+ 
185+         private  static   void  Succeed ( this  Diagnostics . Activity  activity ) 
186+         { 
187+             activity . SetStatus ( Diagnostics . ActivityStatusCode . Ok ) ; 
188+             activity . AddTag ( DiagnosticsStrings . ExitCode ,  0 ) ; 
189+         } 
190+         private  static   void  Error ( this  Diagnostics . Activity  activity ,  int  statusCode ) 
191+         { 
192+             activity . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ; 
193+             activity . AddTag ( DiagnosticsStrings . ExitCode ,  statusCode ) ; 
194+         } 
195+ 
196+         private  static   void  Error ( this  Diagnostics . Activity  activity ,  Exception ?  exception  =  null ) 
197+         { 
198+             activity . SetStatus ( Diagnostics . ActivityStatusCode . Error ) ; 
199+             activity . AddTag ( DiagnosticsStrings . ExitCode ,  1 ) ; 
200+             if  ( exception  is  not null ) 
201+             { 
202+                 activity . AddBaggage ( DiagnosticsStrings . Exception ,  exception . ToString ( ) ) ; 
203+             } 
204+         } 
205+ 
206+         private  static   void  SetExitCode ( this  Diagnostics . Activity  activity ,  int  exitCode ) 
207+         { 
208+             if  ( exitCode  ==  0 ) 
209+             { 
210+                 activity . Succeed ( ) ; 
211+             } 
212+             else 
213+             { 
214+                 activity . Error ( exitCode ) ; 
215+             } 
216+         } 
153217    } 
154218} 
0 commit comments