public void AddCommand(CommandDescriptor commandDescriptor) { foreach (var name in commandDescriptor.GetNames(options)) { if (subCommandDescriptors.ContainsKey(name) || !descriptors.TryAdd(name, commandDescriptor)) { throw new InvalidOperationException($"Duplicate command name is added. Name:{name} Method:{commandDescriptor.MethodInfo.DeclaringType?.Name}.{commandDescriptor.MethodInfo.Name}"); } } }
// Only check command name(not foo) public bool TryGetDescriptor(string[] args, [MaybeNullWhen(false)] out CommandDescriptor descriptor, out int offset) { // 1. Try to match sub command if (args.Length >= 2) { if (subCommandDescriptors.TryGetValue(args[0], out var dict)) { if (dict.TryGetValue(args[1], out descriptor)) { offset = 2; return(true); } else { goto NOTMATCH; } } } // 2. Try to match command if (args.Length >= 1) { if (descriptors.TryGetValue(args[0], out descriptor)) { offset = 1; return(true); } } // 3. default if (rootCommandDescriptor != null) { offset = 0; descriptor = rootCommandDescriptor; return(true); } // not match. NOTMATCH: offset = 0; descriptor = default; return(false); }
public void AddSubCommand(string parentCommand, CommandDescriptor commandDescriptor) { if (descriptors.ContainsKey(parentCommand)) { throw new InvalidOperationException($"Duplicate parent-command is added. Name:{parentCommand} Method:{commandDescriptor.MethodInfo.DeclaringType?.Name}.{commandDescriptor.MethodInfo.Name}"); } if (!subCommandDescriptors.TryGetValue(parentCommand, out var commandDict)) { commandDict = new Dictionary <string, CommandDescriptor>(StringComparer.OrdinalIgnoreCase); subCommandDescriptors.Add(parentCommand, commandDict); } foreach (var name in commandDescriptor.GetNames(options)) { if (!commandDict.TryAdd(name, commandDescriptor)) { throw new InvalidOperationException($"Duplicate command name is added. Name:{parentCommand} {name} Method:{commandDescriptor.MethodInfo.DeclaringType?.Name}.{commandDescriptor.MethodInfo.Name}"); } } }
public ConsoleApp AddCommands <T>() where T : ConsoleAppBase { var methods = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (var method in methods) { if (method.Name == "Dispose" || method.Name == "DisposeAsync") { continue; // ignore IDisposable } if (method.GetCustomAttribute <RootCommandAttribute>() != null || (options.NoAttributeCommandAsImplicitlyDefault && method.GetCustomAttribute <CommandAttribute>() == null)) { var command = new CommandDescriptor(CommandType.DefaultCommand, method); commands.AddRootCommand(command); } else { var command = new CommandDescriptor(CommandType.Command, method); commands.AddCommand(command); } } return(this); }
public bool TryGetVersionMethod([MaybeNullWhen(false)] out CommandDescriptor commandDescriptor) { return(descriptors.TryGetValue(DefaultCommands.Version, out commandDescriptor)); }
public string BuildHelpMessage(CommandDescriptor command) { return(BuildHelpMessage(CreateCommandHelpDefinition(command, false), showCommandName: false, fromMultiCommand: false)); }
internal CommandHelpDefinition CreateCommandHelpDefinition(CommandDescriptor descriptor, bool shortCommandName) { var parameterDefinitions = new List <CommandOptionHelpDefinition>(); foreach (var item in descriptor.MethodInfo.GetParameters()) { // ignore DI params. if (item.ParameterType == typeof(ConsoleAppContext) || (isService != null && isService.IsService(item.ParameterType))) { continue; } // -i, -input | [default=foo]... var index = default(int?); var itemName = this.options.NameConverter(item.Name !); var options = new List <string>(); var option = item.GetCustomAttribute <OptionAttribute>(); if (option != null) { if (option.Index != -1) { index = option.Index; options.Add($"[{option.Index}]"); } else { // If Index is -1, ShortName is initialized at Constractor. if (option.ShortName != null) { options.Add($"-{option.ShortName.Trim('-')}"); } } } if (!index.HasValue) { if (isStrictOption) { options.Add($"--{itemName}"); } else { options.Add($"-{itemName}"); } } var description = string.Empty; if (option != null && !string.IsNullOrEmpty(option.Description)) { description = option.Description ?? string.Empty; } else { description = string.Empty; } var isFlag = item.ParameterType == typeof(bool); var defaultValue = default(string); if (item.HasDefaultValue) { if (option?.DefaultValue != null) { defaultValue = option.DefaultValue; } else { defaultValue = (item.DefaultValue?.ToString() ?? "null"); } if (isFlag) { if (item.DefaultValue is true) { // bool option with true default value is not flag. isFlag = false; } else if (item.DefaultValue is false) { // false default value should be omitted for flag. defaultValue = null; } } } var paramTypeName = item.ParameterType.Name; if (item.ParameterType.IsGenericType && item.ParameterType.GetGenericTypeDefinition() == typeof(Nullable <>)) { paramTypeName = item.ParameterType.GetGenericArguments()[0].Name + "?"; } parameterDefinitions.Add(new CommandOptionHelpDefinition(options.Distinct().ToArray(), description, paramTypeName, defaultValue, index, isFlag)); } return(new CommandHelpDefinition( shortCommandName ? descriptor.GetNamesFormatted(options) : descriptor.GetCommandName(options), descriptor.Aliases, parameterDefinitions.OrderBy(x => x.Index ?? int.MaxValue).ToArray(), descriptor.Description )); }