Пример #1
0
        /// <summary>
        /// Formats a parsed set of arguments back into tokenized string form.
        /// </summary>
        /// <typeparam name="T">Type of the parsed arguments object.</typeparam>
        /// <param name="value">The parsed argument set.</param>
        /// <param name="options">Optionally provides parser options.</param>
        /// <returns>The tokenized string.</returns>
        public static IEnumerable <string> Format <T>(T value, CommandLineParserOptions options)
        {
            var argSet = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet(
                typeof(T),
                attribute: null,
                serviceConfigurer: options?.ServiceConfigurer);

            // N.B. We intentionally convert the arguments enumeration to a list,
            // as we're expecting to mutate it in the loop.
            foreach (var arg in argSet.AllArguments.ToList())
            {
                if (arg.GetValue(value) is IArgumentProvider argProvider)
                {
                    var definingType = argProvider.GetTypeDefiningArguments();
                    if (definingType != null)
                    {
                        AttributeBasedArgumentDefinitionFactory.AddToArgumentSet(argSet, definingType,
                                                                                 fixedDestination: argProvider.GetDestinationObject(),
                                                                                 containingArgument: arg,
                                                                                 serviceConfigurer: options?.ServiceConfigurer);
                    }
                }
            }

            return(OrderArgumentsByContainer(argSet.AllArguments)
                   .Select(arg => new { Argument = arg, Value = arg.GetValue(value) })
                   .Where(argAndValue => (argAndValue.Value != null) && !argAndValue.Value.Equals(argAndValue.Argument.DefaultValue))
                   .SelectMany(argAndValue => argAndValue.Argument.Format(argAndValue.Value))
                   .Where(formattedValue => !string.IsNullOrWhiteSpace(formattedValue)));
        }
Пример #2
0
        /// <summary>
        /// Parses command-line arguments into a reference-type object. Use
        /// ArgumentAttributes to control parsing behavior.
        /// </summary>
        /// <typeparam name="T">Type of the parsed arguments object.</typeparam>
        /// <param name="arguments">The actual arguments.</param>
        /// <param name="destination">The resulting parsed arguments.</param>
        /// <param name="options">Optionally provides additional options
        /// controlling how parsing proceeds.</param>
        /// <returns>True if no errors were detected.</returns>
        public static bool Parse <T>(IEnumerable <string> arguments, T destination, CommandLineParserOptions options) where T : class
        {
            Debug.Assert(arguments != null);
            Debug.Assert(arguments.All(arg => arg != null));
            Debug.Assert(destination != null, "destination cannot be null");

            var engine = new CommandLineParserEngine(destination.GetType(), destination, options);

            return(engine.Parse(arguments, destination));
        }
Пример #3
0
        /// <summary>
        /// Generate possible completions for the specified set of command-line
        /// tokens.
        /// </summary>
        /// <param name="argSet">Argument set definition.</param>
        /// <param name="tokens">The tokens.</param>
        /// <param name="indexOfTokenToComplete">Index of the token to complete.
        /// </param>
        /// <param name="options">Parsing options.</param>
        /// <param name="destObjectFactory">If non-null, provides a factory
        /// function that can be used to create an object suitable to being
        /// filled out by this parser instance.</param>
        /// <returns>The candidate completions for the specified token.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="argSet"/>
        /// or <paramref name="tokens"/> is null.</exception>
        internal static IEnumerable <string> GetCompletions(ArgumentSetDefinition argSet, IEnumerable <string> tokens, int indexOfTokenToComplete, CommandLineParserOptions options, Func <object> destObjectFactory)
        {
            if (argSet == null)
            {
                throw new ArgumentNullException(nameof(argSet));
            }
            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            var parser = new ArgumentSetParser(argSet, options ?? CommandLineParserOptions.Quiet());

            return(parser.GetCompletions(tokens, indexOfTokenToComplete, destObjectFactory));
        }
Пример #4
0
        /// <summary>
        /// Parses command-line arguments into a reference-type object.
        /// Displays usage message if invalid arguments are encountered.
        /// </summary>
        /// <typeparam name="T">Type of the parsed arguments object.</typeparam>
        /// <param name="arguments">The actual arguments.</param>
        /// <param name="destination">The resulting parsed arguments.</param>
        /// <param name="options">Optionally provides additional options
        /// controlling how parsing proceeds.</param>
        /// <param name="usageInfoOptions">Options for how to display usage
        /// information, in case it's presented.</param>
        /// <returns>True if no errors were detected.</returns>
        public static bool ParseWithUsage <T>(IEnumerable <string> arguments, T destination, CommandLineParserOptions options, UsageInfoOptions usageInfoOptions) where T : class
        {
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (options == null)
            {
                options = new CommandLineParserOptions {
                    Reporter = DefaultReporter
                };
            }

            Debug.Assert(arguments.All(a => a != null));

            // Check if the object inherits from HelpArgumentsBase.
            var helpDestination = destination as HelpArgumentsBase;

            // Parse!
            var engine = new CommandLineParserEngine(destination.GetType(), destination, options);

            if (!engine.Parse(arguments, destination))
            {
                // An error was encountered in arguments. Display the usage
                // message.
                options.Reporter?.Invoke(ColoredMultistring.FromString(Environment.NewLine));
                options.Reporter?.Invoke(GetUsageInfo(engine, null, null, usageInfoOptions, destination));

                return(false);
            }

            // We parsed the arguments, but check if we were requested to
            // display the usage help message anyway.
            if ((helpDestination != null) && helpDestination.Help)
            {
                options.Reporter?.Invoke(GetUsageInfo(engine, null, null, usageInfoOptions, destination));
                return(false);
            }

            return(true);
        }
Пример #5
0
        /// <summary>
        /// Tries to parse the given string arguments into a new instance of <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">Type of the destination object; this type should use
        /// appropriate NClap attributes to annotate and define options.</typeparam>
        /// <param name="arguments">The string arguments to parse.</param>
        /// <param name="options">Options describing how to parse.</param>
        /// <param name="result">On success, returns the constructed result object.</param>
        /// <returns>True on success; false otherwise.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="arguments"/>
        /// is null.</exception>
        public static bool TryParse <T>(IEnumerable <string> arguments, CommandLineParserOptions options, out T result)
            where T : class, new()
        {
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            var destination = new T();
            var argSet      = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet(
                destination.GetType(),
                attribute: null,
                defaultValues: destination,
                serviceConfigurer: options?.ServiceConfigurer);

            if (!TryParse(argSet, arguments, options, destination))
            {
                result = null;
                return(false);
            }

            result = destination;
            return(true);
        }
Пример #6
0
 /// <summary>
 /// Parses command-line arguments into a reference-type object.
 /// Displays usage message if invalid arguments are encountered.
 /// </summary>
 /// <typeparam name="T">Type of the parsed arguments object.</typeparam>
 /// <param name="arguments">The actual arguments.</param>
 /// <param name="destination">The resulting parsed arguments.</param>
 /// <param name="options">Optionally provides additional options
 /// controlling how parsing proceeds.</param>
 /// <returns>True if no errors were detected.</returns>
 public static bool ParseWithUsage <T>(IEnumerable <string> arguments, T destination, CommandLineParserOptions options) where T : class =>
 ParseWithUsage(arguments, destination, options, UsageInfoOptions.Default);
Пример #7
0
        /// <summary>
        /// Generate possible completions for the specified set of command-line
        /// tokens.
        /// </summary>
        /// <param name="type">Type of the parsed arguments object.</param>
        /// <param name="tokens">The tokens.</param>
        /// <param name="indexOfTokenToComplete">Index of the token to complete.
        /// </param>
        /// <param name="options">Parsing options.</param>
        /// <param name="destObjectFactory">If non-null, provides a factory
        /// function that can be used to create an object suitable to being
        /// filled out by this parser instance.</param>
        /// <returns>The candidate completions for the specified token.
        /// </returns>
        public static IEnumerable <string> GetCompletions(Type type, IEnumerable <string> tokens, int indexOfTokenToComplete, CommandLineParserOptions options, Func <object> destObjectFactory)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            if (tokens == null)
            {
                throw new ArgumentNullException(nameof(tokens));
            }

            var engine = new CommandLineParserEngine(
                type,
                null /* default values */,
                options);

            return(engine.GetCompletions(tokens, indexOfTokenToComplete, destObjectFactory));
        }
Пример #8
0
 /// <summary>
 /// Generate possible completions for the specified set of command-line
 /// tokens.
 /// </summary>
 /// <param name="type">Type of the parsed arguments object.</param>
 /// <param name="tokens">The tokens.</param>
 /// <param name="indexOfTokenToComplete">Index of the token to complete.
 /// </param>
 /// <param name="options">Parsing options.</param>
 /// <returns>The candidate completions for the specified token.
 /// </returns>
 public static IEnumerable <string> GetCompletions(Type type, IEnumerable <string> tokens, int indexOfTokenToComplete, CommandLineParserOptions options) =>
 GetCompletions(type, tokens, indexOfTokenToComplete, options, null /* object factory */);
Пример #9
0
        public static bool Parse <T>(IEnumerable <string> arguments, ref T destination, CommandLineParserOptions options) where T : struct
        {
            var boxedDestination = (object)destination;

            if (!Parse(arguments, boxedDestination, options))
            {
                return(false);
            }

            destination = (T)boxedDestination;
            return(true);
        }
 /// <summary>
 /// Construct a fluent builder from options.
 /// </summary>
 /// <param name="options">Options.</param>
 /// <returns>Fluent builder.</returns>
 public static FluentBuilder <CommandLineParserOptions> With(this CommandLineParserOptions options) =>
 new FluentBuilder <CommandLineParserOptions>(options.DeepClone());
 /// <summary>
 /// Tries to parse the given string arguments into a new instance of <typeparamref name="T"/>.
 /// </summary>
 /// <typeparam name="T">Type of the destination object; this type should use
 /// appropriate NClap attributes to annotate and define options.</typeparam>
 /// <param name="options">Options describing how to parse.</param>
 /// <param name="arguments">The string arguments to parse.</param>
 /// <param name="result">On success, returns the constructed result object.</param>
 /// <returns>True on success; false otherwise.</returns>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="arguments"/>
 /// is null.</exception>
 public static bool TryParse <T>(this CommandLineParserOptions options, IEnumerable <string> arguments, out T result)
     where T : class, new() =>
 CommandLineParser.TryParse <T>(arguments, options, out result);
Пример #12
0
        /// <summary>
        /// Tries to parse the given string arguments into the provided instance of <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">Type of the destination object; this type should use
        /// appropriate NClap attributes to annotate and define options.</typeparam>
        /// <param name="arguments">The string arguments to parse.</param>
        /// <param name="destination">The object to parse into.</param>
        /// <param name="options">Options describing how to parse.</param>
        /// <returns>True on success; false otherwise.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="arguments"/> or
        /// <paramref name="destination" /> is null.</exception>
        public static bool TryParse <T>(IEnumerable <string> arguments, T destination, CommandLineParserOptions options)
            where T : class
        {
            if (arguments == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(arguments));
            }

            var argSet = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet(
                destination.GetType(),
                attribute: null,
                defaultValues: destination,
                serviceConfigurer: options?.ServiceConfigurer);

            return(TryParse(argSet, arguments, options, destination));
        }
Пример #13
0
        /// <summary>
        /// Generate possible completions for the specified set of command-line
        /// tokens.
        /// </summary>
        /// <param name="type">Type of the parsed arguments object.</param>
        /// <param name="tokens">The tokens.</param>
        /// <param name="indexOfTokenToComplete">Index of the token to complete.
        /// </param>
        /// <param name="options">Parsing options.</param>
        /// <param name="destObjectFactory">If non-null, provides a factory
        /// function that can be used to create an object suitable to being
        /// filled out by this parser instance.</param>
        /// <returns>The candidate completions for the specified token.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="type"/>
        /// or <paramref name="tokens"/> is null.</exception>
        public static IEnumerable <string> GetCompletions(Type type, IEnumerable <string> tokens, int indexOfTokenToComplete, CommandLineParserOptions options, Func <object> destObjectFactory)
        {
            var argSet = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet(
                type,
                attribute: null,
                serviceConfigurer: options?.ServiceConfigurer);

            return(GetCompletions(argSet, tokens, indexOfTokenToComplete, options, destObjectFactory));
        }
Пример #14
0
        /// <summary>
        /// Generate possible completions for the specified command line.
        /// </summary>
        /// <param name="type">Type of the parsed arguments object.</param>
        /// <param name="commandLineToComplete">The command line to complete. Both single and double quote
        /// characters are interpreted as denoting single tokens that may contain embedded whitespace.</param>
        /// <param name="charIndexOfCursor">Character index of the completion cursor.
        /// </param>
        /// <param name="tokensToSkip">Number of tokens to skip from start of command
        /// line.</param>
        /// <param name="options">Parsing options.</param>
        /// <returns>The candidate completions for the specified token.
        /// </returns>
        public static IEnumerable <string> GetCompletions(Type type, string commandLineToComplete, int charIndexOfCursor, int tokensToSkip, CommandLineParserOptions options)
        {
            const TokenizerOptions tokenizerOptions =
                TokenizerOptions.AllowPartialInput |
                TokenizerOptions.HandleDoubleQuoteAsTokenDelimiter |
                TokenizerOptions.HandleSingleQuoteAsTokenDelimiter;

            var tokens = StringUtilities.Tokenize(commandLineToComplete, tokenizerOptions).ToList();

            int index;

            for (index = 0; index < tokens.Count; ++index)
            {
                var token = tokens[index];
                if (charIndexOfCursor >= token.OuterStartingOffset &&
                    charIndexOfCursor <= token.OuterEndingOffset)
                {
                    break;
                }
            }

            if (index < tokensToSkip)
            {
                return(Enumerable.Empty <string>());
            }

            return(GetCompletions(
                       type,
                       tokens.Skip(tokensToSkip).Select(t => t.ToString()),
                       index - tokensToSkip,
                       options));
        }
Пример #15
0
        /// <summary>
        /// Tries to parse the given string arguments into the provided instance of <typeparamref name="T"/>.
        /// </summary>
        /// <typeparam name="T">Type of the destination object.</typeparam>
        /// <param name="argSet">Definition of the argument set to be parsing.</param>
        /// <param name="arguments">The string arguments to parse.</param>
        /// <param name="options">Options describing how to parse.</param>
        /// <param name="destination">The object to parse into.</param>
        /// <returns>True on success; false otherwise.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="arguments"/> or
        /// <paramref name="destination" /> is null.</exception>
        internal static bool TryParse <T>(ArgumentSetDefinition argSet, IEnumerable <string> arguments, CommandLineParserOptions options, T destination)
        {
            if (options == null)
            {
                options = new CommandLineParserOptions();
            }

            //
            // Buffer output to the reporter; suppress it if we find afterwards
            // that the user just wanted to see help information.
            //

            var reportedLines  = new List <ColoredMultistring>();
            var actualReporter = options.Reporter;

            options          = options.DeepClone();
            options.Reporter = s => reportedLines.Add(s);

            //
            // Parse!
            //

            var parser = new ArgumentSetParser(argSet, options);

            var parseResult = parser.ParseArgumentList(arguments, destination).IsReady;

            var parserArgSet = parser.ArgumentSet;

            //
            // See if the user requested help output; if so, then suppress any errors.
            //

            if ((destination is IArgumentSetWithHelp helpArgs) && helpArgs.Help && actualReporter != null)
            {
                actualReporter(GetUsageInfo(parserArgSet, options.HelpOptions, destination));
                return(false);
            }

            //
            // Okay, now flush any reported output.
            //

            if (actualReporter != null)
            {
                foreach (var line in reportedLines)
                {
                    actualReporter.Invoke(line);
                }
            }

            //
            // If we failed to parse and if the caller requested it, then display usage information.
            //

            if (!parseResult && options.DisplayUsageInfoOnError && actualReporter != null)
            {
                actualReporter(ColoredMultistring.FromString(Environment.NewLine));
                actualReporter(GetUsageInfo(parserArgSet, options.HelpOptions, destination));
            }

            return(parseResult);
        }