public int Execute(params string[] args)
        {
            CommandLineApplication        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;
                        string 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)
                            {
                                // a stand-alone "--" is the argument separator, so skip it and
                                // handle the rest of the args as unexpected args
                                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 || 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));

                        // If not a short option, try symbol option
                        if (option == null)
                        {
                            option = command.Options.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 || option.OptionType == CommandOptionType.BoolValue)
                        {
                            // 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());
        }
Пример #2
0
        private ParseOptionResult ParseOption(
            bool isLongOption,
            CommandLineApplication command,
            string[] args,
            ref int index,
            out CommandOption option)
        {
            option = null;
            ParseOptionResult result = ParseOptionResult.Succeeded;
            var arg = args[index];

            int optionPrefixLength = isLongOption ? 2 : 1;

            string[] optionComponents = arg.Substring(optionPrefixLength).Split(new[] { ':', '=' }, 2);
            string   optionName       = optionComponents[0];

            if (isLongOption)
            {
                option = command.Options.SingleOrDefault(
                    opt => string.Equals(opt.LongName, optionName, StringComparison.Ordinal));
            }
            else
            {
                option = command.Options.SingleOrDefault(
                    opt => string.Equals(opt.ShortName, optionName, StringComparison.Ordinal));

                if (option == null)
                {
                    option = command.Options.SingleOrDefault(
                        opt => string.Equals(opt.SymbolName, optionName, StringComparison.Ordinal));
                }
            }

            if (option == null)
            {
                if (isLongOption && string.IsNullOrEmpty(optionName) &&
                    !command._throwOnUnexpectedArg && AllowArgumentSeparator)
                {
                    // a stand-alone "--" is the argument separator, so skip it and
                    // handle the rest of the args as unexpected args
                    index++;
                }

                HandleUnexpectedArg(command, args, index, argTypeName: "option");
                result = ParseOptionResult.UnexpectedArgs;
            }
            else if (command.OptionHelp == option)
            {
                result = ParseOptionResult.ShowHelp;
            }
            else if (command.OptionVersion == option)
            {
                result = ParseOptionResult.ShowVersion;
            }
            else
            {
                if (optionComponents.Length == 2)
                {
                    if (!option.TryParse(optionComponents[1]))
                    {
                        command.ShowHint();
                        throw new CommandParsingException(command,
                                                          String.Format(LocalizableStrings.UnexpectedValueForOptionError, optionComponents[1], optionName));
                    }
                }
                else
                {
                    if (option.OptionType == CommandOptionType.NoValue ||
                        option.OptionType == CommandOptionType.BoolValue)
                    {
                        // No value is needed for this option
                        option.TryParse(null);
                    }
                    else
                    {
                        index++;
                        arg = args[index];
                        if (!option.TryParse(arg))
                        {
                            command.ShowHint();
                            throw new CommandParsingException(
                                      command,
                                      String.Format(LocalizableStrings.UnexpectedValueForOptionError, arg, optionName));
                        }
                    }
                }
            }

            return(result);
        }