public override ValueTask <int> DispatchAsync(CommandDispatchContext ctx)
        {
            var hasHelpOption = ctx.ParsedCommandLine.Options.Any(x => x.Option == BuiltInCommandOption.Help);

            if (hasHelpOption)
            {
                var feature           = _appContext.Current !.Features.Get <ICoconaCommandFeature>() !;
                var commandCollection = feature.CommandCollection ?? _commandProvider.GetCommandCollection();

                var help = (ctx.Command.IsPrimaryCommand)
                    ? _commandHelpProvider.CreateCommandsIndexHelp(commandCollection, feature.CommandStack)
                    : _commandHelpProvider.CreateCommandHelp(ctx.Command, feature.CommandStack);

                _console.Output.Write(_helpRenderer.Render(help));
                return(new ValueTask <int>(129));
            }

            var hasVersionOption = ctx.ParsedCommandLine.Options.Any(x => x.Option == BuiltInCommandOption.Version);

            if (hasVersionOption)
            {
                _console.Output.Write(_helpRenderer.Render(_commandHelpProvider.CreateVersionHelp()));
                return(new ValueTask <int>(0));
            }

            return(Next(ctx));
        }
Example #2
0
        private void ShowDefaultMessage()
        {
            var commandStack      = _appContext.Current !.Features.Get <ICoconaCommandFeature>().CommandStack !;
            var commandCollection = commandStack.LastOrDefault()?.SubCommands ?? _commandProvider.GetCommandCollection();

            _console.Output.Write(_helpRenderer.Render(_commandHelpProvider.CreateCommandsIndexHelp(commandCollection, commandStack)));
        }
        private CommandCollection GetCommandCollectionCore()
        {
            var commandCollection = _underlyingCommandProvider.GetCommandCollection();
            var commands          = commandCollection.All;

            // If the collection has multiple-commands without primary command, use built-in primary command.
            if (commandCollection.All.Count() > 1 && commandCollection.Primary == null)
            {
                commands = commands.Concat(new[] { BuiltInPrimaryCommand.GetCommand(string.Empty) }).ToArray();
            }

            // Rewrite all command names as lower-case and inject built-in help and version help
            var newCommands = new CommandDescriptor[commands.Count];

            for (var i = 0; i < commands.Count; i++)
            {
                var command = commands[i];
                newCommands[i] = new CommandDescriptor(
                    command.Method,
                    command.Name,
                    command.Aliases,
                    command.Description,
                    command.Parameters,
                    GetParametersWithBuiltInOptions(command.Options, command.IsPrimaryCommand),
                    command.Arguments,
                    command.Overloads,
                    command.Flags
                    );
            }

            return(new CommandCollection(newCommands));
        }
        public ValueTask <int> GenerateCompletionSource(
            [FromService] ICoconaConsoleProvider console,
            [FromService] ICoconaCommandProvider commandProvider,
            [FromService] ICoconaShellCompletionCodeProvider shellCompletionCodeProvider,
            [Argument] string shellName
            )
        {
            if (!shellCompletionCodeProvider.CanHandle(shellName))
            {
                console.Error.Write($"Error: Shell completion for '{shellName}' is not supported. (Supported shells: {string.Join(", ", shellCompletionCodeProvider.SupportedTargets)})");
                return(new ValueTask <int>(1));
            }

            shellCompletionCodeProvider.Generate(shellName, console.Output, commandProvider.GetCommandCollection());
            return(new ValueTask <int>(0));
        }
        private HelpMessage BuildFromCurrentContextCore(bool respectCurrentCommand)
        {
            var feature           = _appContext.Current !.Features.Get <ICoconaCommandFeature>() !;
            var commandCollection = feature.CommandCollection ?? _commandProvider.GetCommandCollection(); // nested or root

            // If `respectCurrentCommand` is `true`, treats the current command as a target.
            // When called by `--help`, the original command is put on the CommandStack.
            // When directly call the method, the CommandStack may be empty.
            var targetCommand = respectCurrentCommand ? feature.Command : feature.CommandStack.LastOrDefault();

            var help = targetCommand is null
                ? _commandHelpProvider.CreateCommandsIndexHelp(commandCollection, Array.Empty <CommandDescriptor>())
                : targetCommand.IsPrimaryCommand || targetCommand.Flags.HasFlag(CommandFlags.SubCommandsEntryPoint)
                    ? _commandHelpProvider.CreateCommandsIndexHelp(commandCollection, feature.CommandStack.Take(feature.CommandStack.Count - 1).ToArray())
                    : _commandHelpProvider.CreateCommandHelp(targetCommand, feature.CommandStack.Take(feature.CommandStack.Count - 1).ToArray());

            return(help);
        }
Example #6
0
        public override ValueTask <int> DispatchAsync(CommandDispatchContext ctx)
        {
            var hasHelpOption = ctx.ParsedCommandLine.Options.Any(x => x.Option == BuiltInCommandOption.Help);

            if (hasHelpOption)
            {
                var help = (ctx.Command.IsPrimaryCommand)
                    ? _commandHelpProvider.CreateCommandsIndexHelp(_commandProvider.GetCommandCollection())
                    : _commandHelpProvider.CreateCommandHelp(ctx.Command);

                _console.Output.Write(_helpRenderer.Render(help));
                return(new ValueTask <int>(129));
            }

            var hasVersionOption = ctx.ParsedCommandLine.Options.Any(x => x.Option == BuiltInCommandOption.Version);

            if (hasVersionOption)
            {
                _console.Output.Write(_helpRenderer.Render(_commandHelpProvider.CreateVersionHelp()));
                return(new ValueTask <int>(0));
            }

            return(Next(ctx));
        }
Example #7
0
        public async ValueTask <int> DispatchAsync(CancellationToken cancellationToken)
        {
            var commandCollection = _commandProvider.GetCommandCollection();
            var args            = _commandLineArgumentProvider.GetArguments();
            var subCommandStack = new List <CommandDescriptor>();

Retry:
            var matchedCommand = default(CommandDescriptor);

            if (commandCollection.All.Count == 1 && !commandCollection.All[0].Flags.HasFlag(CommandFlags.SubCommandsEntryPoint))
            {
                // single-command style
                matchedCommand = commandCollection.All[0];
            }
            else if (commandCollection.All.Count > 0)
            {
                // multi-commands hosted style
                if (_commandLineParser.TryGetCommandName(args, out var commandName))
                {
                    if (!_commandMatcher.TryGetCommand(commandName, commandCollection, out matchedCommand))
                    {
                        throw new CommandNotFoundException(
                                  commandName,
                                  commandCollection,
                                  $"The specified command '{commandName}' was not found."
                                  );
                    }

                    // NOTE: Skip a first argument that is command name.
                    args = args.Skip(1).ToArray();

                    // If the command have nested sub-commands, try to restart parse command.
                    if (matchedCommand.SubCommands != null)
                    {
                        commandCollection = matchedCommand.SubCommands;
                        subCommandStack.Add(matchedCommand);
                        goto Retry;
                    }
                }
                else
                {
                    // Use default command (NOTE: The default command must have no argument.)
                    matchedCommand = commandCollection.Primary ?? throw new CommandNotFoundException("", commandCollection, "A primary command was not found.");
                }
            }

            // Found a command and dispatch.
            if (matchedCommand != null)
            {
                // resolve command overload
                if (matchedCommand.Overloads.Any())
                {
                    // Try parse command-line for overload resolution by options.
                    var preParsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options, matchedCommand.Arguments);
                    matchedCommand = _commandMatcher.ResolveOverload(matchedCommand, preParsedCommandLine);
                }

                var parsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options, matchedCommand.Arguments);
                var dispatchAsync     = _dispatcherPipelineBuilder.Build();

                // Activate a command type.
                var commandInstance = _activator.GetServiceOrCreateInstance(_serviceProvider, matchedCommand.CommandType);
                if (commandInstance == null)
                {
                    throw new InvalidOperationException($"Unable to activate command type '{matchedCommand.CommandType.FullName}'");
                }

                // Set CoconaAppContext
                _appContext.Current = new CoconaAppContext(matchedCommand, cancellationToken);
                _appContext.Current.Features.Set <ICoconaCommandFeature>(new CoconaCommandFeature(commandCollection, matchedCommand, subCommandStack, commandInstance));

                // Dispatch the command
                try
                {
                    var ctx = new CommandDispatchContext(matchedCommand, parsedCommandLine, commandInstance, cancellationToken);
                    return(await dispatchAsync(ctx));
                }
                finally
                {
                    if (commandInstance is IDisposable disposable)
                    {
                        disposable.Dispose();
                    }
                }
            }

            throw new CommandNotFoundException(
                      string.Empty,
                      commandCollection,
                      $"Command not yet implemented."
                      );
        }
Example #8
0
 public CommandCollection GetCommandCollection()
 {
     return(_cachedCommandCollection ??= GetWrappedCommandCollection(_underlyingCommandProvider.GetCommandCollection()));
 }
Example #9
0
        public CommandResolverResult ParseAndResolve(IReadOnlyList <string> args)
        {
            var commandCollection = _commandProvider.GetCommandCollection();
            var subCommandStack   = new List <CommandDescriptor>();

Retry:
            var matchedCommand = default(CommandDescriptor);

            if (commandCollection.All.Count == 1 && !commandCollection.All[0].Flags.HasFlag(CommandFlags.SubCommandsEntryPoint))
            {
                // single-command style
                matchedCommand = commandCollection.All[0];
            }
            else if (commandCollection.All.Count > 0)
            {
                // multi-commands hosted style
                if (_commandLineParser.TryGetCommandName(args, out var commandName))
                {
                    if (!_commandMatcher.TryGetCommand(commandName, commandCollection, out matchedCommand))
                    {
                        throw new CommandNotFoundException(
                                  commandName,
                                  commandCollection,
                                  $"The specified command '{commandName}' was not found."
                                  );
                    }

                    // NOTE: Skip a first argument that is command name.
                    args = args.Skip(1).ToArray();

                    // If the command has nested sub-commands, try to restart parse command.
                    if (matchedCommand.SubCommands != null)
                    {
                        commandCollection = matchedCommand.SubCommands;
                        subCommandStack.Add(matchedCommand);
                        goto Retry;
                    }
                }
                else
                {
                    // Use default command (NOTE: The default command must have no argument.)
                    matchedCommand = commandCollection.Primary ?? throw new CommandNotFoundException("", commandCollection, "A primary command was not found.");
                }
            }

            // Found a command and dispatch.
            if (matchedCommand != null)
            {
                // resolve command overload
                if (matchedCommand.Overloads.Any())
                {
                    // Try parse command-line for overload resolution by options.
                    var preParsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options.OfType <ICommandOptionDescriptor>().Concat(matchedCommand.OptionLikeCommands).ToArray(), matchedCommand.Arguments);
                    matchedCommand = _commandMatcher.ResolveOverload(matchedCommand, preParsedCommandLine);
                }

                var parsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options.OfType <ICommandOptionDescriptor>().Concat(matchedCommand.OptionLikeCommands).ToArray(), matchedCommand.Arguments);

                // OptionLikeCommand
                if (parsedCommandLine.Options.FirstOrDefault(x => x.Option is CommandOptionLikeCommandDescriptor) is var commandOption &&
                    commandOption.Option is CommandOptionLikeCommandDescriptor optionLikeCommand)
                {
                    subCommandStack.Add(matchedCommand);
                    matchedCommand    = optionLikeCommand.Command;
                    parsedCommandLine = _commandLineParser.ParseCommand(args.Skip(commandOption.Position + 1).ToArray(), matchedCommand.Options, matchedCommand.Arguments);
                }

                return(new CommandResolverResult(true, commandCollection, parsedCommandLine, matchedCommand, subCommandStack));
            }

            return(new CommandResolverResult(false, commandCollection, null, null, null));
        }
Example #10
0
        public async ValueTask <int> DispatchAsync(CancellationToken cancellationToken)
        {
            var commandCollection = _commandProvider.GetCommandCollection();
            var args = _commandLineArgumentProvider.GetArguments();

            var matchedCommand = default(CommandDescriptor);

            if (commandCollection.All.Count > 1)
            {
                // multi-commands hosted style
                if (_commandLineParser.TryGetCommandName(args, out var commandName))
                {
                    if (!_commandMatcher.TryGetCommand(commandName, commandCollection, out matchedCommand))
                    {
                        throw new CommandNotFoundException(
                                  commandName,
                                  commandCollection,
                                  $"The specified command '{commandName}' was not found."
                                  );
                    }

                    // NOTE: Skip a first argument that is command name.
                    args = args.Skip(1).ToArray();
                }
                else
                {
                    // Use default command (NOTE: The default command must have no argument.)
                    matchedCommand = commandCollection.Primary ?? throw new CommandNotFoundException("", commandCollection, "A primary command was not found.");
                }
            }
            else
            {
                // single-command style
                if (commandCollection.All.Any())
                {
                    matchedCommand = commandCollection.All[0];
                }
            }

            // Found a command and dispatch.
            if (matchedCommand != null)
            {
                // resolve command overload
                if (matchedCommand.Overloads.Any())
                {
                    // Try parse command-line for overload resolution by options.
                    var preParsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options, matchedCommand.Arguments);
                    matchedCommand = _commandMatcher.ResolveOverload(matchedCommand, preParsedCommandLine);
                }

                var parsedCommandLine = _commandLineParser.ParseCommand(args, matchedCommand.Options, matchedCommand.Arguments);
                var dispatchAsync     = _dispatcherPipelineBuilder.Build();

                // Set CoconaAppContext
                _appContext.Current = new CoconaAppContext(cancellationToken);

                // Dispatch command.
                var commandInstance = _activator.GetServiceOrCreateInstance(_serviceProvider, matchedCommand.CommandType);
                try
                {
                    var ctx = new CommandDispatchContext(matchedCommand, parsedCommandLine, commandInstance !, cancellationToken);
                    return(await dispatchAsync(ctx));
                }
                finally
                {
                    if (commandInstance is IDisposable disposable)
                    {
                        disposable.Dispose();
                    }
                }
            }

            throw new CommandNotFoundException(
                      string.Empty,
                      commandCollection,
                      $"Command not yet implemented."
                      );
        }
Example #11
0
 private void ShowDefaultMessage()
 {
     _console.Output.Write(_helpRenderer.Render(_commandHelpProvider.CreateCommandsIndexHelp(_commandProvider.GetCommandCollection())));
 }