public void Execute(CommandParameters parameters) { var matches = MatchCommands(parameters); if (matches.Count() == 1) { var match = matches.Single(); match.CommandHandlerFactory().Execute(match.Context); } else { var commandMatch = string.Join(" ", parameters.Arguments.ToArray()); var commandList = string.Join(",", GetCommandDescriptors().Select(d => d.Name).ToArray()); if (matches.Any()) { throw new TomeltCoreException(T("Multiple commands found matching arguments \"{0}\". Commands available: {1}.", commandMatch, commandList)); } throw new TomeltCoreException(T("No command found matching arguments \"{0}\". Commands available: {1}.", commandMatch, commandList)); } }
private static IEnumerable <Match> MatchCommands(CommandParameters parameters, int argCount, CommandHandlerDescriptor descriptor, Func <ICommandHandler> handlerFactory) { foreach (var commandDescriptor in descriptor.Commands) { var names = commandDescriptor.Name.Split(' '); if (!parameters.Arguments.Take(argCount).SequenceEqual(names, StringComparer.OrdinalIgnoreCase)) { // leading arguments not equal to command name continue; } yield return(new Match { Context = new CommandContext { Arguments = parameters.Arguments.Skip(names.Count()), Command = string.Join(" ", names), CommandDescriptor = commandDescriptor, Input = parameters.Input, Output = parameters.Output, Switches = parameters.Switches, }, CommandHandlerFactory = handlerFactory }); } }
public CommandReturnCodes RunCommand(TextReader input, TextWriter output, string tenant, string[] args, Dictionary <string, string> switches) { try { tenant = tenant ?? ShellSettings.DefaultName; using (var env = CreateStandaloneEnvironment(tenant)) { var commandManager = env.Resolve <ICommandManager>(); ITransactionManager transactionManager; if (!env.TryResolve(out transactionManager)) { transactionManager = null; } var parameters = new CommandParameters { Arguments = args, Switches = switches, Input = input, Output = output }; try { commandManager.Execute(parameters); } catch { // any database changes in this using(env) scope are invalidated if (transactionManager != null) { transactionManager.Cancel(); } // exception handling performed below throw; } } // in effect "pump messages" see PostMessage circa 1980 var processingEngine = _hostContainer.Resolve <IProcessingEngine>(); while (processingEngine.AreTasksPending()) { processingEngine.ExecuteNextTask(); } return(CommandReturnCodes.Ok); } catch (TomeltCommandHostRetryException ex) { // Special "Retry" return code for our host output.WriteLine(T("{0} (Retrying...)", ex.Message)); return(CommandReturnCodes.Retry); } catch (Exception ex) { if (ex.IsFatal()) { throw; } if (ex is TargetInvocationException && ex.InnerException != null) { // If this is an exception coming from reflection and there is an innerexception which is the actual one, redirect ex = ex.InnerException; } OutputException(output, T("Error executing command \"{0}\"", string.Join(" ", args)), ex); return(CommandReturnCodes.Fail); } }