示例#1
0
        private static Task <int> SetDefaults(CommandContext context, ExecutionDelegate next)
        {
            if (context.ParseResult.ParseError != null)
            {
                return(next(context));
            }

            var config  = context.AppConfig.Services.Get <Config>();
            var command = context.ParseResult.TargetCommand;

            foreach (var argument in command.AllArguments(true))
            {
                var value = config.GetDefaultValueCallbacks.Select(func => func(argument)).FirstOrDefault();
                if (value != null)
                {
                    if (argument.Arity.AllowsMany())
                    {
                        argument.DefaultValue = value.Split(',');
                    }
                    else
                    {
                        argument.DefaultValue = value;
                    }
                }
            }

            return(next(context));
        }
示例#2
0
        private static Task <int> DataAnnotationsValidation(CommandContext ctx, ExecutionDelegate next)
        {
            var errors = ctx.InvocationPipeline.All
                         .SelectMany(ValidateStep)
                         .ToList();

            if (errors.Any())
            {
                var console = ctx.Console;
                errors.ForEach(error =>
                {
                    console.Error.WriteLine(error);
                });

                ctx.ShowHelpOnExit = ctx.AppConfig.Services.GetOrThrow <Config>().ShowHelpOnError;

                if (ctx.ShowHelpOnExit)
                {
                    console.Error.WriteLine();
                }

                return(ExitCodes.ValidationError);
            }

            return(next(ctx));
        }
示例#3
0
        private static Task <int> TypoSuggest(CommandContext ctx, ExecutionDelegate next)
        {
            if (ctx.ParseResult !.ParseError != null)
            {
                switch (ctx.ParseResult.ParseError)
                {
                case UnrecognizedArgumentParseError unrecognizedArgument:
                    if (TrySuggestArgumentNames(ctx, unrecognizedArgument.Command, unrecognizedArgument.Token))
                    {
                        // in case help was requested by CommandParser
                        ctx.ShowHelpOnExit = false;
                        return(ExitCodes.Error);
                    }

                    // TODO: suggest other directives? We'd need a list of names which we don't collect atm.
                    break;

                case NotAllowedValueParseError notAllowedValue:
                    if (TrySuggestValues(ctx, notAllowedValue))
                    {
                        // in case help was requested by CommandParser
                        ctx.ShowHelpOnExit = false;
                        return(ExitCodes.Error);
                    }

                    break;
                }
            }

            return(next(ctx));
        }
        private static Task <int> InjectTestOutputs(CommandContext commandContext, ExecutionDelegate next)
        {
            var outputs = commandContext.AppConfig.Services.Get <TestOutputs>();

            commandContext.InvocationPipeline.All
            .Select(i => i.Instance)
            .ForEach(instance =>
            {
                instance.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                .Where(p => p.PropertyType == typeof(TestOutputs))
                .ForEach(p =>
                {
                    // principal of least surprise
                    // if the test class sets the instance, then use that instance
                    var value = (TestOutputs)p.GetValue(instance);
                    if (value == null)
                    {
                        p.SetValue(instance, outputs);
                    }
                    else
                    {
                        outputs.UseOutputsFromInstance(value);
                    }
                });
            });
            return(next(commandContext));
        }
示例#5
0
            public object Invoke(CommandContext commandContext, object instance, ExecutionDelegate next)
            {
                if (_nextParameterInfo != null)
                {
                    if (next == null)
                    {
                        throw new InvalidConfigurationException(
                                  $"Invalid operation. {nameof(ExecutionDelegate)} {_nextParameterInfo.Name} parameter not provided for method: {_nextParameterInfo.Member.FullName()}. " +
                                  $"Check middleware to ensure it hasn't misconfigured the {nameof(CommandContext.InvocationPipeline)}");
                    }

                    if (_nextParameterInfo.ParameterType == InterceptorNextParameterType)
                    {
                        var nextLite = new InterceptorExecutionDelegate(() => next(commandContext));
                        Values[_nextParameterInfo.Position] = nextLite;
                    }
                    else
                    {
                        Values[_nextParameterInfo.Position] = next;
                    }
                }

                _resolvers?.ForEach(r => r(commandContext));

                return(_methodInfo.Invoke(instance, Values));
            }
        private static Task <int> CreateRootCommand(CommandContext commandContext, ExecutionDelegate next)
        {
            var config = commandContext.AppConfig.Services.GetOrThrow <Config>();

            commandContext.RootCommand = ClassCommandDef.CreateRootCommand(config.RootCommandType, commandContext);
            return(next(commandContext));
        }
示例#7
0
        private static Task <int> CheckIfShouldShowHelp(CommandContext ctx, ExecutionDelegate next)
        {
            var parseResult   = ctx.ParseResult;
            var targetCommand = parseResult.TargetCommand;

            if (parseResult.ParseError != null)
            {
                var console = ctx.Console;
                console.Error.WriteLine(parseResult.ParseError.Message);
                console.Error.WriteLine();
                ctx.ShowHelpOnExit = true;
                return(ExitCodes.Error);
            }

            if (parseResult.HelpWasRequested())
            {
                ctx.ShowHelpOnExit = true;
                return(ExitCodes.Success);
            }

            if (!targetCommand.IsExecutable)
            {
                ctx.ShowHelpOnExit = true;
                return(ExitCodes.Success);
            }

            return(next(ctx));
        }
        private static Task <int> InjectPipedInputToOperandList(CommandContext ctx, ExecutionDelegate next)
        {
            if (ctx.Console.IsInputRedirected)
            {
                // supporting only the list operand for a command gives us a few benefits
                // 1. there can be only one list operand per command.
                //    no need to enforce this only one argument has EnablePipedInput=true
                // 2. no need to handle case where a single value operand has EnablePipedInput=true
                //    otherwise we either drop all but the first value or throw an exception
                //    both have pros & cons
                // 3. List operands are specified and provided last, avoiding awkward cases
                //    where piped input is provided for arguments positioned before others.
                //    We'd need to inject additional middleware to inject tokens in this case.
                // 4. piped values can be merged with args passed to the command.
                //    this can become an option passed into appBuilder.EnablePipedInput(...)
                //    if a need arises to throw instead of merge
                var operand = ctx.ParseResult.TargetCommand.Operands
                              .FirstOrDefault(o => o.Arity.AllowsMany());

                if (operand == null)
                {
                    Log.DebugFormat("No list operands found for {0}", ctx.ParseResult.TargetCommand.Name);
                }
                else
                {
                    Log.DebugFormat("Piping input to {0}.{1}", ctx.ParseResult.TargetCommand.Name, operand.Name);
                    operand.InputValues.Add(new InputValue(Constants.InputValueSources.Piped, true, GetPipedInput(ctx.Console)));
                }
            }

            return(next(ctx));
        }
        private static Task <int> SetDefaults(
            CommandContext context,
            ExecutionDelegate next,
            IDictionary <string, object> defaults)
        {
            if (context.ParseResult.ParseError != null)
            {
                return(next(context));
            }

            var command     = context.ParseResult.TargetCommand;
            var interceptor = command.Parent;

            var arguments = command.Options.Cast <IArgument>().Union(command.Operands);

            if (interceptor != null)
            {
                arguments = arguments.Union(interceptor.Options).Union(interceptor.Operands);
            }

            foreach (var argument in arguments)
            {
                if (defaults.TryGetValue(argument.Name, out var value))
                {
                    argument.DefaultValue = value;
                }
            }

            return(next(context));
        }
示例#10
0
        private static Task <int> CheckCulture(CommandContext context, ExecutionDelegate next)
        {
            Action?revert = null;

            if (context.Tokens.TryGetDirective("culture", out string?culture))
            {
                var name        = culture !.Split(':').Last();
                var cultureInfo = CultureInfo.GetCultureInfo(name);

                var previousCulture   = CultureInfo.CurrentCulture;
                var previousUICulture = CultureInfo.CurrentUICulture;

                revert = () =>
                {
                    CultureInfo.CurrentCulture   = previousCulture;
                    CultureInfo.CurrentUICulture = previousUICulture;
                };

                CultureInfo.CurrentCulture   = cultureInfo;
                CultureInfo.CurrentUICulture = cultureInfo;
            }

            var result = next(context);

            // revert for tests and interactive repl sessions
            revert?.Invoke();

            return(result);
        }
示例#11
0
        private static Task <int> DisplayHelp(CommandContext commandContext, ExecutionDelegate next)
        {
            var parseResult   = commandContext.ParseResult;
            var targetCommand = parseResult.TargetCommand;

            if (parseResult.ParseError != null)
            {
                var console = commandContext.Console;
                console.Error.WriteLine(parseResult.ParseError.Message);
                console.Error.WriteLine();
                Print(commandContext, targetCommand);
                return(Task.FromResult(1));
            }

            if (parseResult.HelpWasRequested())
            {
                Print(commandContext, targetCommand);
                return(Task.FromResult(0));
            }

            if (!targetCommand.IsExecutable)
            {
                Print(commandContext, targetCommand);
                return(Task.FromResult(0));
            }

            return(next(commandContext));
        }
        private static Task <int> AlertOnNewVersion(CommandContext context, ExecutionDelegate next)
        {
            var config = context.AppConfig.Services.Get <NewerReleaseConfig>();

            var skipCommand = config.SkipCommand?.Invoke(context.ParseResult.TargetCommand) ?? false;

            if (!skipCommand)
            {
                SemVersion latestReleaseVersion = null;

                var shouldAlert = TryGetCurrentVersion(context, out var currentVersion) &&
                                  TryGetLatestReleaseVersion(context, config, out latestReleaseVersion) &&
                                  currentVersion < latestReleaseVersion;
                if (shouldAlert)
                {
                    var message = $"A newer release exists. Current:{currentVersion} Latest:{latestReleaseVersion}";
                    if (config.PostfixAlertMessageCallback != null)
                    {
                        message += $" {config.PostfixAlertMessageCallback?.Invoke(latestReleaseVersion.ToString())}";
                    }

                    context.Console.Out.WriteLine(message);
                    context.Console.Out.WriteLine();
                }
            }

            return(next(context));
        }
            static Task <int> Invoke(InvocationStep step, CommandContext context, ExecutionDelegate next, bool isCommand)
            {
                var result = step.Invocation.Invoke(context, step.Instance !, next);

                return(isCommand
                    ? result.GetResultCodeAsync()
                    : (Task <int>)result);
            }
示例#14
0
 /// <summary>
 /// Builds a full command
 /// </summary>
 /// <param name="commandString">The command</param>
 /// <param name="description">Description</param>
 /// <param name="runCommand">The delegate called when command invoked</param>
 /// <param name="requiredArgs">The # of required args</param>
 /// <param name="usage">The usage string</param>
 public DebugCommand(string commandString, string description, ExecutionDelegate runCommand, int requiredArgs, string usage)
 {
     this.Command = commandString;
     this.Description = description;
     this._Execute = runCommand;
     this.NumRequiredArgs = requiredArgs;
     this.Usage = usage;
 }
 public Task <int> Intercept(CommandContext context, ExecutionDelegate next)
 {
     TestOutputs.Capture(new Services
     {
         FromCtor        = _someService,
         FromInterceptor = (ISomeService)context.AppConfig.DependencyResolver.Resolve(typeof(ISomeService))
     });
     return(next(context));
 }
        private static Task <int> InjectPipedInputToOperandList(CommandContext ctx, ExecutionDelegate next)
        {
            if (ctx.Console.IsInputRedirected)
            {
                AssignPipedInput(ctx);
            }

            return(next(ctx));
        }
示例#17
0
        private static Task <int> RunInScope(CommandContext context, ExecutionDelegate next)
        {
            var config = context.AppConfig.Services.GetOrThrow <Config>();

            using (config.RunInScopeCallback(context))
            {
                return(next(context));
            }
        }
 /// <summary>
 /// Initializes a new instance with the specified <see cref="IDocumentBuilder"/>,
 /// <see cref="IDocumentValidator"/>, <see cref="IComplexityAnalyzer"/>,
 /// <see cref="IDocumentCache"/> and a set of <see cref="IConfigureExecutionOptions"/> instances.
 /// </summary>
 private DocumentExecuter(IDocumentBuilder documentBuilder, IDocumentValidator documentValidator, IComplexityAnalyzer complexityAnalyzer, IDocumentCache documentCache, IExecutionStrategySelector executionStrategySelector, IEnumerable <IConfigureExecution> configurations)
 {
     // TODO: in v6 make this public
     _documentBuilder           = documentBuilder ?? throw new ArgumentNullException(nameof(documentBuilder));
     _documentValidator         = documentValidator ?? throw new ArgumentNullException(nameof(documentValidator));
     _complexityAnalyzer        = complexityAnalyzer ?? throw new ArgumentNullException(nameof(complexityAnalyzer));
     _documentCache             = documentCache ?? throw new ArgumentNullException(nameof(documentCache));
     _executionStrategySelector = executionStrategySelector ?? throw new ArgumentNullException(nameof(executionStrategySelector));
     _execution = BuildExecutionDelegate(configurations);
 }
示例#19
0
 public void ExecuteNextFrame(ExecutionDelegate func)
 {
     lock (this)
     {
         ExecutionListBuffer.Add(new ExecutionData()
         {
             ExecuteFunction      = func,
             ExecuteAfterGameTime = -1
         });
     }
 }
示例#20
0
        private static Task <int> PrintHelp(CommandContext ctx, ExecutionDelegate next)
        {
            var result = next(ctx);

            if (ctx.ShowHelpOnExit)
            {
                ctx.PrintHelp();
            }

            return(result);
        }
示例#21
0
        private static Task <int> DisplayVersionIfSpecified(CommandContext commandContext,
                                                            ExecutionDelegate next)
        {
            if (commandContext.RootCommand.HasInputValues(VersionOptionName))
            {
                Print(commandContext, commandContext.Console);
                return(Task.FromResult(0));
            }

            return(next(commandContext));
        }
        private static Task <int> DisplayVersionIfSpecified(CommandContext commandContext,
                                                            ExecutionDelegate next)
        {
            if (commandContext.RootCommand !.HasInputValues(VersionOptionName))
            {
                Print(commandContext.Console);
                return(ExitCodes.Success);
            }

            return(next(commandContext));
        }
        private static Task <int> DisableConsoleLogging(CommandContext context, ExecutionDelegate next)
        {
            if (context.ParseResult.TargetCommand.CustomAttributes.IsDefined(typeof(DisableConsoleLoggingAttribute),
                                                                             false))
            {
                LogManager.Configuration.RemoveTarget("logconsole");
                LogManager.ReconfigExistingLoggers();
            }

            return(next(context));
        }
示例#24
0
 public void ExecuteInSeconds(float time, ExecutionDelegate func)
 {
     lock (this)
     {
         ExecutionListBuffer.Add(new ExecutionData()
         {
             ExecuteFunction      = func,
             ExecuteAfterGameTime = lastFrameTime + time
         });
     }
 }
示例#25
0
        private static T Crud <T>(string tablename, List <KeyValuePair <string, int> > primaryKey,
                                  DataTable table, CrudDelegate f, ExecutionDelegate <T> execsql)
        {
            SqlCommand cmd = new SqlCommand(f(table, ExtractKeys <string, int>(primaryKey)));

            foreach (KeyValuePair <string, int> kvp in primaryKey)
            {
                SqlCommandUtils.AddInputParam(cmd, kvp.Key, kvp.Value);
            }

            return(execsql(cmd, table));
        }
示例#26
0
        // adapted from https://github.com/dotnet/command-line-api directives
        private static Task <int> AttachDebugger(CommandContext commandContext, ExecutionDelegate next)
        {
            if (commandContext.Tokens.HasDebugDirective())
            {
                Debugger.Attach(
                    commandContext.CancellationToken,
                    commandContext.Console,
                    commandContext.AppConfig.Services.GetOrThrow <DebugDirectiveContext>().WaitForDebuggerToAttach);
            }

            return(next(commandContext));
        }
        private ExecutionDelegate BuildExecutionDelegate(IEnumerable <IConfigureExecution> configurations)
        {
            ExecutionDelegate execution = CoreExecuteAsync;
            var configurationArray      = configurations.ToArray();

            for (var i = configurationArray.Length - 1; i >= 0; i--)
            {
                var action        = configurationArray[i];
                var nextExecution = execution;
                execution = async options => await action.ExecuteAsync(options, nextExecution).ConfigureAwait(false);
            }
            return(execution);
        }
示例#28
0
 public object?Invoke(CommandContext commandContext, object instance, ExecutionDelegate next)
 {
     WasInvoked = true;
     try
     {
         return(_backingInvocation.Invoke(commandContext, instance, next));
     }
     catch (Exception e)
     {
         InvocationError = e;
         throw;
     }
 }
        private static Task <int> LogToConsole(CommandContext context, ExecutionDelegate next)
        {
            if (context.Tokens.TryGetDirective("log", out var logDirective))
            {
                var parts = logDirective.Split(':', '=');
                var level = parts.Length > 1
                    ? (LogLevel)Enum.Parse(typeof(LogLevel), parts[1], ignoreCase: true)
                    : LogLevel.Trace;
                var dateTimeFormat = GetDateTimeFormat(parts);
                LogProvider.SetCurrentLogProvider(new ConsoleLogProvider(context.Console, level, dateTimeFormat));
            }

            return(next(context));
        }
示例#30
0
        private static Task <int> TimerDirective(CommandContext context, ExecutionDelegate next)
        {
            if (context.Original.Tokens.TryGetDirective("time", out _))
            {
                var sw     = Stopwatch.StartNew();
                var result = next(context);
                sw.Stop();
                context.Console.WriteLine();
                context.Console.WriteLine($"time: {sw.Elapsed}");
                return(result);
            }

            return(next(context));
        }
示例#31
0
        public (WalkerContext, IList <Transition>) execute(
            ProcessContext context, WalkerContext token)
        {
            ExecutionDelegate next = (c, t) => Task.CompletedTask;

            foreach (var exec in this._executions)
            {
                next = exec(next);
            }

            next(context, token).Wait();

            return(token, this.OutgoingTransitions);
        }