#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); }
/// <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(); }
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); }
/// <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>(); }
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(); }
/// <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)); }
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, }); }
/// <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)); }
/// <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);
/// <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); }