예제 #1
0
 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}");
         }
     }
 }
예제 #2
0
        // 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);
        }
예제 #3
0
        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}");
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 public bool TryGetVersionMethod([MaybeNullWhen(false)] out CommandDescriptor commandDescriptor)
 {
     return(descriptors.TryGetValue(DefaultCommands.Version, out commandDescriptor));
 }
예제 #6
0
 public string BuildHelpMessage(CommandDescriptor command)
 {
     return(BuildHelpMessage(CreateCommandHelpDefinition(command, false), showCommandName: false, fromMultiCommand: false));
 }
예제 #7
0
        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
                       ));
        }