private void CreateSubApplications(Type type, CommandLineApplication parentApplication, IDependencyResolver dependencyResolver) { IEnumerable <Type> propertySubmodules = type.GetDeclaredProperties <SubCommandAttribute>() .Select(p => p.PropertyType); IEnumerable <Type> inlineClassSubmodules = type .GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) .Where(x => x.HasAttribute <SubCommandAttribute>()) .Where(x => !x.IsCompilerGenerated()) .Where(x => !typeof(IAsyncStateMachine).IsAssignableFrom(x)); foreach (Type submoduleType in propertySubmodules.Union(inlineClassSubmodules)) { // TODO: optimization - return a LazyAppCreator, parsing sub applications only as needed // the current code creates all sub applications // for an app like git with a lot of commands this can have a noticeable impact // this accounts for ~10% of the run time across all feature tests AppCreator appCreator = new AppCreator(_appSettings); appCreator.CreateApplication(submoduleType, dependencyResolver, parentApplication); } }
private void CreateSubApplications(Type type, CommandLineApplication parentApplication, IDependencyResolver dependencyResolver) { IEnumerable <Type> propertySubmodules = type.GetDeclaredProperties <SubCommandAttribute>() .Select(p => p.PropertyType); IEnumerable <Type> inlineClassSubmodules = type .GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) .Where(x => x.HasAttribute <SubCommandAttribute>()) .Where(x => !x.IsCompilerGenerated()) .Where(x => !typeof(IAsyncStateMachine).IsAssignableFrom(x)); foreach (Type submoduleType in propertySubmodules.Union(inlineClassSubmodules)) { AppCreator appCreator = new AppCreator(_appSettings); appCreator.CreateApplication(submoduleType, dependencyResolver, parentApplication); } }
/// <summary> /// Executes the specified command with given parameters /// </summary> /// <param name="args">Command line arguments</param> /// <returns>If target method returns int, this method will return that value. Else, /// it will return 0 in case of success and 1 in case of unhandled exception</returns> public int Run(params string[] args) { try { AppCreator appCreator = new AppCreator(_settings); CommandLineApplication app = appCreator.CreateApplication(typeof(T), DependencyResolver); return(app.Execute(_parserBuilder.Build(), args)); } catch (AppRunnerException e) { _settings.Error.WriteLine(e.Message + "\n"); #if DEBUG _settings.Error.WriteLine(e.StackTrace); #endif return(1); } catch (CommandParsingException e) { var optionHelp = e.Command.OptionHelp; if (optionHelp != null) { _settings.Out.WriteLine( $"Specify --{optionHelp.LongName} for a list of available options and commands."); } _settings.Error.WriteLine(e.Message + "\n"); e.Command.ShowHelp(); #if DEBUG _settings.Error.WriteLine(e.StackTrace); #endif return(1); } catch (ValueParsingException e) { _settings.Error.WriteLine(e.Message + "\n"); return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is AppRunnerException) || e.InnerExceptions.Any(x => x.GetBaseException() is CommandParsingException)) { foreach (var innerException in e.InnerExceptions) { _settings.Error.WriteLine(innerException.GetBaseException().Message + "\n"); #if DEBUG _settings.Error.WriteLine(innerException.GetBaseException().StackTrace); if (e.InnerExceptions.Count > 1) { _settings.Error.WriteLine("-----------------------------------------------------------------"); } #endif } return(1); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is ArgumentValidationException)) { ArgumentValidationException validationException = (ArgumentValidationException)e.InnerExceptions.FirstOrDefault(x => x.GetBaseException() is ArgumentValidationException); foreach (var failure in validationException.ValidationResult.Errors) { _settings.Out.WriteLine(failure.ErrorMessage); } return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is ValueParsingException) ) { ValueParsingException valueParsingException = (ValueParsingException)e.InnerExceptions.FirstOrDefault(x => x.GetBaseException() is ValueParsingException); _settings.Error.WriteLine(valueParsingException.Message + "\n"); return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x is TargetInvocationException)) { TargetInvocationException ex = (TargetInvocationException)e.InnerExceptions.SingleOrDefault(x => x is TargetInvocationException); ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(1); // this will never be called } catch (AggregateException e) { foreach (Exception innerException in e.InnerExceptions) { ExceptionDispatchInfo.Capture(innerException).Throw(); } return(1); // this will never be called if there is any inner exception } catch (ArgumentValidationException ex) { foreach (var failure in ex.ValidationResult.Errors) { _settings.Out.WriteLine(failure.ErrorMessage); } return(2); } catch (TargetInvocationException ex) { ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(1); // this will never be called } }
/// <summary> /// Exceutes the specified command with given parameters /// </summary> /// <param name="args">Command line arguments</param> /// <returns>If target method returns int, this method will return that value. Else, /// it will return 0 in case of successs and 1 in case of unhandled exception</returns> public int Run(params string[] args) { try { AppCreator appCreator = new AppCreator(_settings); CommandLineApplication app = appCreator.CreateApplication(typeof(T), DependencyResolver); var parsedArguments = ArgumentParser.SplitFlags(args).ToArray(); return(app.Execute(parsedArguments)); } catch (AppRunnerException e) { Console.Error.WriteLine(e.Message + "\n"); #if DEBUG Console.Error.WriteLine(e.StackTrace); #endif return(1); } catch (CommandParsingException e) { Console.Error.WriteLine(e.Message + "\n"); e.Command.ShowHelp(); #if DEBUG Console.Error.WriteLine(e.StackTrace); #endif return(1); } catch (ValueParsingException e) { Console.Error.WriteLine(e.Message + "\n"); return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is AppRunnerException) || e.InnerExceptions.Any(x => x.GetBaseException() is CommandParsingException)) { foreach (var innerException in e.InnerExceptions) { Console.Error.WriteLine(innerException.GetBaseException().Message + "\n"); #if DEBUG Console.Error.WriteLine(innerException.GetBaseException().StackTrace); if (e.InnerExceptions.Count > 1) { Console.Error.WriteLine("-----------------------------------------------------------------"); } #endif } return(1); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is ArgumentValidationException)) { ArgumentValidationException validationException = (ArgumentValidationException)e.InnerExceptions.FirstOrDefault(x => x.GetBaseException() is ArgumentValidationException); foreach (var failure in validationException.ValidationResult.Errors) { Console.WriteLine(failure.ErrorMessage); } return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x.GetBaseException() is ValueParsingException)) { ValueParsingException valueParsingException = (ValueParsingException)e.InnerExceptions.FirstOrDefault(x => x.GetBaseException() is ValueParsingException); Console.Error.WriteLine(valueParsingException.Message + "\n"); return(2); } catch (AggregateException e) when(e.InnerExceptions.Any(x => x is TargetInvocationException)) { TargetInvocationException ex = (TargetInvocationException)e.InnerExceptions.SingleOrDefault(x => x is TargetInvocationException); ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(1); // this will never be called } catch (AggregateException e) { foreach (Exception innerException in e.InnerExceptions) { ExceptionDispatchInfo.Capture(innerException).Throw(); } return(1); // this will never be called if there is any inner exception } catch (ArgumentValidationException ex) { foreach (var failure in ex.ValidationResult.Errors) { Console.WriteLine(failure.ErrorMessage); } return(2); } catch (TargetInvocationException ex) { ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); return(1); // this will never be called } }