Esempio n. 1
0
        /// <summary>
        /// Resolves <see cref="CommandSchema"/>.
        /// </summary>
        public static CommandSchema Resolve(Type type, IReadOnlyList <Type>?modeTypes)
        {
            if (!KnownTypesHelpers.IsCommandType(type))
            {
                throw CommandResolverExceptions.InvalidCommandType(type);
            }

            CommandAttribute attribute = type.GetCustomAttribute <CommandAttribute>() !;

            if (modeTypes != null)
            {
                if (attribute.SupportedModes != null && attribute.SupportedModes.Except(modeTypes).Any())
                {
                    throw CommandResolverExceptions.InvalidSupportedModesInCommand(type, attribute);
                }

                if (attribute.ExcludedModes != null && attribute.ExcludedModes.Except(modeTypes).Any())
                {
                    throw CommandResolverExceptions.InvalidExcludedModesInCommand(type, attribute);
                }
            }


            string?name = attribute.Name;

            CommandOptionSchema[] builtInOptions = string.IsNullOrWhiteSpace(name)
                ? new[] { CommandOptionSchema.HelpOption, CommandOptionSchema.VersionOption }
                : new[] { CommandOptionSchema.HelpOption };

            CommandParameterSchema?[] parameters = type.GetProperties()
                                                   .Select(CommandParameterSchemaResolver.TryResolve)
                                                   .Where(p => p != null)
                                                   .OrderBy(p => p !.Order)
                                                   .ToArray();

            CommandOptionSchema?[] options = type.GetProperties()
                                             .Select(CommandOptionSchemaResolver.TryResolve)
                                             .Where(o => o != null)
                                             .Concat(builtInOptions)
                                             .ToArray();

            CommandSchema command = new CommandSchema(
                type,
                name,
                attribute.Description,
                attribute.Manual,
                attribute.SupportedModes,
                attribute.ExcludedModes,
                parameters !,
                options !
                );

            ValidateParameters(command);
            ValidateOptions(command);

            return(command);
        }
Esempio n. 2
0
        private void ResolveCommands(IReadOnlyList <Type> commandTypes)
        {
            CommandSchema?defaultCommand  = null;
            var           commands        = new Dictionary <string, CommandSchema>();
            var           invalidCommands = new List <CommandSchema>();

            foreach (Type commandType in commandTypes)
            {
                CommandSchema command = CommandSchemaResolver.Resolve(commandType, _modeTypes);

                if (command.IsDefault)
                {
                    defaultCommand = defaultCommand is null ? command : throw CommandResolverExceptions.TooManyDefaultCommands();
                }
                else if (!commands.TryAdd(command.Name !, command))
                {
                    invalidCommands.Add(command);
                }
            }

            if (commands.Count == 0 && defaultCommand is null)
            {
                throw CommandResolverExceptions.NoCommandsDefined();
            }

            if (invalidCommands.Count > 0)
            {
                IGrouping <string, CommandSchema> duplicateNameGroup = invalidCommands.Union(commands.Values)
                                                                       .GroupBy(c => c.Name !, StringComparer.Ordinal)
                                                                       .First();

                throw CommandResolverExceptions.CommandsWithSameName(duplicateNameGroup.Key, duplicateNameGroup.ToArray());
            }

            DefaultCommand = defaultCommand;
            Commands       = commands;
        }