private bool ProcessCommandOrArgument()
        {
            var arg = _enumerator.Current;

            foreach (var subcommand in _currentCommand.Commands)
            {
                if (string.Equals(subcommand.Name, arg.Raw, StringComparison.OrdinalIgnoreCase))
                {
                    _currentCommand = subcommand;
                    return(true);
                }
            }

            if (_currentCommandArguments == null)
            {
                _currentCommandArguments = new CommandArgumentEnumerator(_currentCommand.Arguments.GetEnumerator());
            }

            if (_currentCommandArguments.MoveNext())
            {
                _currentCommandArguments.Current.Values.Add(arg.Raw);
            }
            else
            {
                HandleUnexpectedArg("command or argument");
                return(false);
            }

            return(true);
        }
        public int Execute(params string[] args)
        {
            var command = this;
            IEnumerator <CommandArgument> arguments = null;

            if (HandleResponseFiles)
            {
                args = ExpandResponseFiles(args).ToArray();
            }

            for (var index = 0; index < args.Length; index++)
            {
                var arg = args[index];

                var isLongOption = arg.StartsWith("--", StringComparison.Ordinal);
                if (isLongOption || arg.StartsWith("-", StringComparison.Ordinal))
                {
                    var result = ParseOption(isLongOption, command, args, ref index, out var option);
                    if (result == ParseOptionResult.ShowHelp)
                    {
                        command.ShowHelp();
                        return(1);
                    }
                    else if (result == ParseOptionResult.ShowVersion)
                    {
                        command.ShowVersion();
                        return(0);
                    }
                }
                else
                {
                    var subcommand = ParseSubCommand(arg, command);
                    if (subcommand != null)
                    {
                        command = subcommand;
                    }
                    else
                    {
                        if (arguments == null)
                        {
                            arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
                        }

                        if (arguments.MoveNext())
                        {
                            arguments.Current.Values.Add(arg);
                        }
                        else
                        {
                            HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
                        }
                    }
                }

                arguments?.Dispose();
            }

            return(command.Invoke());
        }
 public CommandLineApplication Process()
 {
     _currentCommand          = _initialCommand;
     _currentCommandArguments = null;
     while (_enumerator.MoveNext())
     {
         if (!ProcessNext())
         {
             return(_currentCommand);
         }
     }
     _enumerator.Reset();
     return(_currentCommand);
 }
        public ParseResult Process()
        {
            var parseResult = new ParseResult();

            _currentCommand          = _initialCommand;
            _currentCommandArguments = null;
            while (_enumerator.MoveNext())
            {
                if (!ProcessNext())
                {
                    goto finished;
                }
            }
            _enumerator.Reset();

finished:
            parseResult.SelectedCommand = _currentCommand;
            return(parseResult);
        }
        public int Execute(params string[] args)
        {
            CommandLineApplication        command   = this;
            CommandOption                 option    = null;
            IEnumerator <CommandArgument> arguments = null;

            for (var index = 0; index < args.Length; index++)
            {
                var arg       = args[index];
                var processed = false;
                if (!processed && option == null)
                {
                    string[] longOption  = null;
                    string[] shortOption = null;

                    if (arg.StartsWith("--"))
                    {
                        longOption = arg.Substring(2).Split(new[] { ':', '=' }, 2);
                    }
                    else if (arg.StartsWith("-"))
                    {
                        shortOption = arg.Substring(1).Split(new[] { ':', '=' }, 2);
                    }
                    if (longOption != null)
                    {
                        processed = true;
                        var longOptionName = longOption[0];
                        option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.LongName, longOptionName, StringComparison.Ordinal));

                        if (option == null)
                        {
                            if (string.IsNullOrEmpty(longOptionName) && !_appSettings.ThrowOnUnexpectedArgument && _appSettings.AllowArgumentSeparator)
                            {
                                // skip over the '--' argument separator
                                index++;
                            }

                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }

                        // If we find a help/version option, show information and stop parsing
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            return(0);
                        }
                        else if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            return(0);
                        }

                        if (longOption.Length == 2)
                        {
                            if (!option.TryParse(longOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{longOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue)
                        {
                            // No value is needed for this option
                            option.TryParse(null);
                            option = null;
                        }
                    }
                    if (shortOption != null)
                    {
                        processed = true;
                        option    = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.ShortName, shortOption[0], StringComparison.Ordinal));

                        // If not a short option, try symbol option
                        if (option == null)
                        {
                            option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.SymbolName, shortOption[0], StringComparison.Ordinal));
                        }

                        if (option == null)
                        {
                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }

                        // If we find a help/version option, show information and stop parsing
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            return(0);
                        }
                        else if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            return(0);
                        }

                        if (shortOption.Length == 2)
                        {
                            if (!option.TryParse(shortOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{shortOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue)
                        {
                            // No value is needed for this option
                            option.TryParse(null);
                            option = null;
                        }
                    }
                }

                if (!processed && option != null)
                {
                    processed = true;
                    if (!option.TryParse(arg))
                    {
                        command.ShowHint();
                        throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{option.LongName}'");
                    }
                    option = null;
                }

                if (!processed && arguments == null)
                {
                    var currentCommand = command;
                    foreach (var subcommand in command.Commands)
                    {
                        if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
                        {
                            processed = true;
                            command   = (CommandLineApplication)subcommand;
                            break;
                        }
                    }

                    // If we detect a subcommand
                    if (command != currentCommand)
                    {
                        processed = true;
                    }
                }
                if (!processed)
                {
                    if (arguments == null)
                    {
                        arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
                    }
                    if (arguments.MoveNext())
                    {
                        processed = true;
                        arguments.Current.Values.Add(arg);
                    }
                }
                if (!processed)
                {
                    HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
                    break;
                }
            }

            if (option != null)
            {
                command.ShowHint();
                throw new CommandParsingException(command, $"Missing value for option '{option.LongName}'");
            }

            return(command.Invoke());
        }
        private int Execute(List <string> args)
        {
            CommandLineApplication        command   = this;
            CommandOption                 option    = null;
            IEnumerator <CommandArgument> arguments = null;

            for (var index = 0; index < args.Count; index++)
            {
                var arg = args[index];

                if (command.HandleResponseFiles && index > _responseFileArgsEnd && arg.Length > 1 && arg[0] == '@')
                {
                    var path     = arg.Substring(1);
                    var fullPath = Path.IsPathRooted(path)
                        ? path
                        : Path.Combine(command.WorkingDirectory, path);
                    var rspArgs = ResponseFileParser.Parse(fullPath);
                    args.InsertRange(index + 1, rspArgs);
                    _responseFileArgsEnd = index + rspArgs.Count;
                    continue;
                }

                var processed = false;
                if (!processed && option == null)
                {
                    string[] longOption  = null;
                    string[] shortOption = null;

                    if (arg != null)
                    {
                        if (arg.StartsWith("--"))
                        {
                            longOption = arg.Substring(2).Split(new[] { ':', '=' }, 2);
                        }
                        else if (arg.StartsWith("-"))
                        {
                            shortOption = arg.Substring(1).Split(new[] { ':', '=' }, 2);
                        }
                    }

                    if (longOption != null)
                    {
                        processed = true;
                        var longOptionName = longOption[0];
                        option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.LongName, longOptionName, StringComparison.Ordinal));

                        if (option == null)
                        {
                            if (string.IsNullOrEmpty(longOptionName) && !command.ThrowOnUnexpectedArgument && AllowArgumentSeparator)
                            {
                                // skip over the '--' argument separator
                                index++;
                            }

                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }

                        // If we find a help/version option, show information and stop parsing
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            option.TryParse(null);
                            return(0);
                        }
                        else if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            option.TryParse(null);
                            return(0);
                        }

                        if (longOption.Length == 2)
                        {
                            if (!option.TryParse(longOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{longOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue)
                        {
                            // No value is needed for this option
                            option.TryParse(null);
                            option = null;
                        }
                    }

                    if (shortOption != null)
                    {
                        processed = true;
                        option    = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.ShortName, shortOption[0], StringComparison.Ordinal));

                        // If not a short option, try symbol option
                        if (option == null)
                        {
                            option = command.GetOptions().SingleOrDefault(opt => string.Equals(opt.SymbolName, shortOption[0], StringComparison.Ordinal));
                        }

                        if (option == null)
                        {
                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }

                        // If we find a help/version option, show information and stop parsing
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            return(0);
                        }
                        else if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            return(0);
                        }

                        if (shortOption.Length == 2)
                        {
                            if (!option.TryParse(shortOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{shortOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue)
                        {
                            // No value is needed for this option
                            option.TryParse(null);
                            option = null;
                        }
                    }
                }

                if (!processed && option != null)
                {
                    processed = true;
                    if (!option.TryParse(arg))
                    {
                        command.ShowHint();
                        throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{option.LongName}'");
                    }
                    option = null;
                }

                if (!processed && arguments == null)
                {
                    var currentCommand = command;
                    foreach (var subcommand in command.Commands)
                    {
                        if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
                        {
                            processed = true;
                            command   = subcommand;
                            break;
                        }
                    }

                    // If we detect a subcommand
                    if (command != currentCommand)
                    {
                        processed = true;
                    }
                }
                if (!processed)
                {
                    if (arguments == null)
                    {
                        arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
                    }
                    if (arguments.MoveNext())
                    {
                        processed = true;
                        arguments.Current.Values.Add(arg);
                    }
                }
                if (!processed)
                {
                    HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
                    break;
                }
            }

            if (option != null)
            {
                command.ShowHint();
                throw new CommandParsingException(command, $"Missing value for option '{option.LongName}'");
            }

            return(command.Invoke());
        }
Esempio n. 7
0
        public int Execute(params string[] args)
        {
            CommandLineApplication    command   = this;
            CommandArgumentEnumerator arguments = null;

            if (HandleResponseFiles)
            {
                args = ExpandResponseFiles(args).ToArray();
            }

            for (var index = 0; index < args.Length; index++)
            {
                var arg = args[index];

                bool isLongOption = arg.StartsWith("--");
                if (arg == "-?" || arg == "/?")
                {
                    command.ShowHelp();
                    return(0);
                }
                else if (isLongOption || arg.StartsWith("-"))
                {
                    CommandOption option;

                    var result = ParseOption(isLongOption, command, args, ref index, out option);


                    if (result == ParseOptionResult.ShowHelp)
                    {
                        command.ShowHelp();
                        return(0);
                    }
                    else if (result == ParseOptionResult.ShowVersion)
                    {
                        command.ShowVersion();
                        return(0);
                    }
                    else if (result == ParseOptionResult.UnexpectedArgs)
                    {
                        break;
                    }
                }
                else
                {
                    var subcommand = ParseSubCommand(arg, command);
                    if (subcommand != null)
                    {
                        command = subcommand;
                    }
                    else
                    {
                        if (arguments == null || arguments.CommandName != command.Name)
                        {
                            arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator(), command.Name);
                        }

                        if (arguments.MoveNext())
                        {
                            arguments.Current.Values.Add(arg);
                        }
                        else
                        {
                            HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
                            break;
                        }
                    }
                }
            }

            if (Commands.Count > 0 && command == this)
            {
                throw new CommandParsingException(
                          command,
                          "Required command missing",
                          isRequireSubCommandMissing: true);
            }

            return(command.Invoke());
        }
        public async Task <int> Execute(params string[] args)
        {
            var           command = this;
            CommandOption option  = null;
            IEnumerator <CommandArgument> arguments = null;

            if (HandleResponseFiles)
            {
                args = ExpandResponseFiles(args).ToArray();
            }

            for (var index = 0; index < args.Length; index++)
            {
                var arg       = args[index];
                var processed = false;
                if (!processed && option == null)
                {
                    string[] longOption  = null;
                    string[] shortOption = null;

                    if (arg.StartsWith("--"))
                    {
                        longOption = arg.Substring(2).Split(new[] { ':', '=' }, 2);
                    }
                    else if (arg.StartsWith("-"))
                    {
                        shortOption = arg.Substring(1).Split(new[] { ':', '=' }, 2);
                    }
                    if (longOption != null)
                    {
                        processed = true;
                        var longOptionName = longOption[0];
                        option = command.Options.SingleOrDefault(opt => string.Equals(opt.LongName, longOptionName, StringComparison.Ordinal));

                        if (option == null)
                        {
                            if (string.IsNullOrEmpty(longOptionName) && !command._throwOnUnexpectedArg && AllowArgumentSeparator)
                            {
                                index++;
                            }

                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            return(0);
                        }
                        if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            return(0);
                        }

                        if (longOption.Length == 2)
                        {
                            if (!option.TryParse(longOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{longOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue || option.OptionType == CommandOptionType.BoolValue)
                        {
                            // No value is needed for this option
                            option.TryParse(null);
                            option = null;
                        }
                    }
                    if (shortOption != null)
                    {
                        processed = true;
                        option    = command.Options.SingleOrDefault(opt => string.Equals(opt.ShortName, shortOption[0], StringComparison.Ordinal)) ??
                                    command.Options.SingleOrDefault(opt => string.Equals(opt.SymbolName, shortOption[0], StringComparison.Ordinal));

                        if (option == null)
                        {
                            HandleUnexpectedArg(command, args, index, argTypeName: "option");
                            break;
                        }
                        if (command.OptionHelp == option)
                        {
                            command.ShowHelp();
                            return(0);
                        }
                        if (command.OptionVersion == option)
                        {
                            command.ShowVersion();
                            return(0);
                        }

                        if (shortOption.Length == 2)
                        {
                            if (!option.TryParse(shortOption[1]))
                            {
                                command.ShowHint();
                                throw new CommandParsingException(command, $"Unexpected value '{shortOption[1]}' for option '{option.LongName}'");
                            }
                            option = null;
                        }
                        else if (option.OptionType == CommandOptionType.NoValue || option.OptionType == CommandOptionType.BoolValue)
                        {
                            option.TryParse(null);
                            option = null;
                        }
                    }
                }

                if (!processed && option != null)
                {
                    processed = true;
                    if (!option.TryParse(arg))
                    {
                        command.ShowHint();
                        throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{option.LongName}'");
                    }
                    option = null;
                }

                if (!processed && arguments == null)
                {
                    var currentCommand = command;
                    foreach (var subcommand in
                             command.Commands.Where(subcommand => string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase)))
                    {
                        processed = true;
                        command   = subcommand;
                        break;
                    }
                    if (command != currentCommand)
                    {
                        processed = true;
                    }
                }
                if (!processed)
                {
                    if (arguments == null)
                    {
                        arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
                    }
                    if (arguments.MoveNext())
                    {
                        processed = true;
                        arguments.Current.Values.Add(arg);
                    }
                }
                if (processed)
                {
                    continue;
                }
                HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
                break;
            }

            switch (option)
            {
            case null:
                return(await command.Invoke());

            default:
                command.ShowHint();
                throw new CommandParsingException(command, $"Missing value for option '{option.LongName}'");
            }
        }
Esempio n. 9
0
        public ParseResult ParseCommand(CommandLineApplication app, string[] args)
        {
            CommandLineApplication        currentCommand = app;
            CommandOption                 currentOption  = null;
            IEnumerator <CommandArgument> arguments      = new CommandArgumentEnumerator(app.Arguments);

            var remainingArguments = new List <Token>();

            var tokens = args.Tokenize(includeDirectives: _appSettings.EnableDirectives);

            tokens = ApplyArgumentTransformations(tokens);

            if (_parserContext.ParseDirectiveEnabled)
            {
                return(new ParseResult(app, args, tokens, exitCode: 0));
            }

            bool ignoreRemainingArguments = false;

            foreach (var token in tokens)
            {
                if (ignoreRemainingArguments)
                {
                    remainingArguments.Add(token);
                    continue;
                }

                switch (token.TokenType)
                {
                case TokenType.Option:
                    var optionResult = ParseOption(token, currentCommand, out currentOption);
                    switch (optionResult)
                    {
                    case ParseOptionResult.Succeeded:
                        break;

                    case ParseOptionResult.UnexpectedArgument:
                        ignoreRemainingArguments = true;
                        break;

                    case ParseOptionResult.ShowHelp:
                        currentCommand.ShowHelp();
                        return(new ParseResult(currentCommand, args, tokens, exitCode: 0));

                    case ParseOptionResult.ShowVersion:
                        app.ShowVersion();
                        return(new ParseResult(currentCommand, args, tokens, exitCode: 0));

                    default:
                        throw new ArgumentOutOfRangeException(optionResult.ToString());
                    }
                    break;

                case TokenType.Argument:
                    var argumentResult = ParseArgument(token, ref currentCommand, ref currentOption, arguments);
                    switch (argumentResult)
                    {
                    case ParseArgumentResult.Succeeded:
                        break;

                    case ParseArgumentResult.UnexpectedArgument:
                        ignoreRemainingArguments = true;
                        break;

                    case ParseArgumentResult.NewSubCommand:
                        arguments = new CommandArgumentEnumerator(currentCommand.Arguments);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(argumentResult.ToString());
                    }
                    break;

                case TokenType.Separator:
                    ignoreRemainingArguments = true;
                    break;

                case TokenType.Directive:
                    throw new ArgumentOutOfRangeException($"Directives should have already been processed and removed: {token.RawValue}");

                default:
                    throw new ArgumentOutOfRangeException($"Unknown {nameof(TokenType)}: {token.TokenType}");
                }
            }

            if (currentOption != null) // an option was left without a value
            {
                throw new CommandParsingException(currentCommand, $"Missing value for option '{currentOption.LongName}'");
            }

            return(new ParseResult(currentCommand, args, tokens, unparsedTokens: new Tokens(remainingArguments)));
        }