Exemple #1
0
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters

        /// <summary>
        /// Constructor that requires an explicit implementation of
        /// <see cref="ILoopClient"/>.
        /// </summary>
        /// <param name="commandType">Type that defines syntax for commands.</param>
        /// <param name="loopClient">The client to use.</param>
        /// <param name="argSetAttribute">Optionally provides attribute info
        /// for the argument set that will be dynamically created for this loop.</param>
        /// <param name="options">Optionally provides additional options for
        /// this loop's execution.</param>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="commandType" />
        /// is null.</exception>
        public Loop(Type commandType, ILoopClient loopClient, ArgumentSetAttribute argSetAttribute = null, LoopOptions options = null)
        {
            if (commandType == null)
            {
                throw new ArgumentNullException(nameof(commandType));
            }

            _client = loopClient ?? throw new ArgumentNullException(nameof(loopClient));
            _client.TokenCompleter = new TokenCompleter(this);

            _options = options?.DeepClone() ?? new LoopOptions();
            _options.ParserOptions.DisplayUsageInfoOnError = false;
            _options.ParserOptions.Reporter = error => _client.OnError(error.ToString().TrimEnd());

            var inputConfigurer = _options.ParserOptions.ServiceConfigurer;

            _options.ParserOptions.ServiceConfigurer = collection => ConfigureServices(collection, inputConfigurer);

            var constructedType = ConstructCommandTypeFactory(commandType, out _objectFactory);

            _argSet = AttributeBasedArgumentDefinitionFactory.CreateArgumentSet(
                constructedType,
                attribute: argSetAttribute,
                serviceConfigurer: _options.ParserOptions.ServiceConfigurer);
        }
Exemple #2
0
        /// <summary>
        /// Gets the default logo for the given argument set.
        /// </summary>
        /// <param name="set">Optionally provides the argument set to
        /// get the logo for.</param>
        /// <returns>The logo.</returns>
        public static string GetLogo(ArgumentSetDefinition set = null)
        {
            string logo;
            bool   expand;

            if (set?.Attribute.Logo != null)
            {
                logo   = (string)set.Attribute.Logo;
                expand = set.Attribute.ExpandLogo;
            }
            else
            {
                logo   = DefaultLogoFormat;
                expand = true;
            }

            if (expand)
            {
                var assembly = set?.DefaultAssembly ?? Assembly.GetEntryAssembly() ?? typeof(ArgumentSetUsageInfo).GetTypeInfo().Assembly;
                var factory  = new LogoFactory(assembly);

                if (factory.TryExpand(logo, out string expandedLogo))
                {
                    logo = expandedLogo;
                }
                else
                {
                    logo = string.Empty;
                }
            }

            return(logo);
        }
        public void TestThatConstructorAllowNullOptions()
        {
            var    argSet = new ArgumentSetDefinition();
            Action a      = () => new ArgumentSetParser(argSet, null);

            a.Should().NotThrow();
        }
Exemple #4
0
        private static IReadOnlyList <ArgumentUsageInfo> GetParameters(ArgumentSetDefinition argSet, object destination)
        {
            var parameters = new List <ArgumentUsageInfo>();

            // Enumerate positional arguments first, in position order.
            foreach (var arg in argSet.PositionalArguments.Where(a => !a.Hidden))
            {
                var currentValue = (destination != null) ? arg.GetValue(destination) : null;
                parameters.Add(new ArgumentUsageInfo(arg, currentValue));
            }

            // Enumerate named arguments next, in case-insensitive sort order.
            var stringComparer = argSet.Attribute.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;

            foreach (var arg in argSet.NamedArguments
                     .Where(a => !a.Hidden)
                     .OrderBy(a => a.LongName, stringComparer))
            {
                var currentValue = (destination != null) ? arg.GetValue(destination) : null;
                parameters.Add(new ArgumentUsageInfo(arg, currentValue));
            }

            // TODO: Add an extra item for answer files, if that is supported on this
            // argument set.

            return(parameters);
        }
Exemple #5
0
        /// <summary>
        /// Renders the given usage information.
        /// </summary>
        /// <param name="argSet">Argument set.</param>
        /// <param name="destination">Destination object.</param>
        /// <returns>Rendered string output, ready for display.</returns>
        public ColoredMultistring Format(ArgumentSetDefinition argSet, object destination)
        {
            var info = new ArgumentSetUsageInfo(argSet, destination);

            var unorderedSections = GenerateSections(info);

            var orderedSections = SortSections(unorderedSections, DefaultSectionOrdering);

            return(Format(orderedSections));
        }
        public void TestThatArgumentDefinitionCanBeBackedByField()
        {
            var argSet = new ArgumentSetDefinition();

            Action a = () => new ArgumentDefinition(
                typeof(TestClassWithField).GetField(nameof(TestClassWithField.MyValue)),
                new NamedArgumentAttribute(),
                argSet);

            a.Should().NotThrow();
        }
        public void TestThatArgumentDefinitionCannotBeBackedByEvent()
        {
            var argSet = new ArgumentSetDefinition();

            Action a = () => new ArgumentDefinition(
                typeof(TestClassWithEvent).GetEvent(nameof(TestClassWithEvent.MyEvent)),
                new NamedArgumentAttribute(),
                argSet);

            a.Should().Throw <NotSupportedException>();
        }
Exemple #8
0
        private string SerializeSummary(ArgumentSetDefinition argSet)
        {
            var argSetSummary = Summarize(argSet);

            var serializer = new JsonSerializerSettings
            {
                NullValueHandling    = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };

            return(JsonConvert.SerializeObject(argSetSummary, Formatting.Indented, serializer));
        }
        public void TestThatConstructorAllowsOptionsWithNullProperties()
        {
            var argSet  = new ArgumentSetDefinition();
            var options = new CommandLineParserOptions
            {
                Context          = null,
                FileSystemReader = null,
                HelpOptions      = null,
                Reporter         = null
            };

            Action a = () => new ArgumentSetParser(argSet, options);

            a.Should().NotThrow();
        }
        private ArgumentDefinition CreateArg <T>(bool required = false, object defaultValue = null)
        {
            var argSet = new ArgumentSetDefinition();
            var attrib = new NamedArgumentAttribute(required ? ArgumentFlags.Required : ArgumentFlags.Optional);

            if (defaultValue != null)
            {
                attrib.DefaultValue = defaultValue;
            }

            return(new ArgumentDefinition(
                       typeof(TestArguments <T>).GetTypeInfo().GetMember(nameof(TestArguments <T> .Value)).Single(),
                       attrib,
                       argSet));
        }
        private ArgumentSetDefinition DefineArgSet(IEnumerable <ArgumentBaseAttribute> argAttribs = null, ArgumentSetAttribute setAttrib = null)
        {
            var set = new ArgumentSetDefinition(setAttrib);

            if (argAttribs != null)
            {
                foreach (var argAttrib in argAttribs)
                {
                    var arg = DefineArg(set, argAttrib);
                    set.Add(arg);
                }
            }

            return(set);
        }
        public void TestThatGetLogoYieldsEmptyStringLogoCannotBeExpanded()
        {
            var attrib = new ArgumentSetAttribute
            {
                Logo       = "{",
                ExpandLogo = true
            };

            var argSet    = new ArgumentSetDefinition(attrib);
            var usageInfo = new ArgumentSetUsageInfo(argSet, null);

            var logo = usageInfo.Logo;

            logo.Should().BeEmpty();
        }
Exemple #13
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));
        }
Exemple #14
0
        private ArgumentSetSummary Summarize(ArgumentSetDefinition argSet)
        {
            return(new ArgumentSetSummary
            {
                description = argSet.Attribute.Description,
                assembly = _programArgs.LoadedAssembly.FullName,
                type = _programArgs.LoadedType.Name,

                args = argSet.AllArguments
                       .Where(arg => !arg.Attribute.Hidden)
                       .Select(arg => Summarize(arg))
                       .ToArray(),

                examples = argSet.Attribute.Examples,
            });
        }
Exemple #15
0
        /// <summary>
        /// Returns a usage string for command line argument parsing.
        /// </summary>
        /// <param name="argSet">Definition of argument set.</param>
        /// <param name="options">Options for generating usage info.</param>
        /// <param name="destination">Optionally provides an object with
        /// default values.</param>
        /// <returns>Printable string containing a user friendly description of
        /// command line arguments.</returns>
        internal static ColoredMultistring GetUsageInfo(
            ArgumentSetDefinition argSet,
            ArgumentSetHelpOptions options,
            object destination)
        {
            // Default options.
            if (options == null)
            {
                options = new ArgumentSetHelpOptions();
            }

            // Default max width.
            if (!options.MaxWidth.HasValue)
            {
                options = options.With().MaxWidth(GetCurrentConsoleWidth());
            }

            // Construct renderer.
            var renderer = new ArgumentSetHelpRenderer(options);

            // Render.
            return(renderer.Format(argSet, destination));
        }
Exemple #16
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="argSet">Argument set.</param>
 /// <param name="destination">Destination object.</param>
 public ArgumentSetUsageInfo(ArgumentSetDefinition argSet, object destination)
 {
     Set           = argSet;
     Destination   = destination;
     AllParameters = GetParameters(argSet, destination);
 }
 private ArgumentDefinition DefineArg(ArgumentSetDefinition set, ArgumentBaseAttribute argAttrib) =>
 new ArgumentDefinition(
     typeof(TestArgumentSet).GetProperty(nameof(TestArgumentSet.SomeProperty)),
     argAttrib,
     set);
Exemple #18
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);
        }