internal static IArgument ToArgument(this IArgumentDef argumentDef, AppConfig appConfig, bool isInterceptorOption)
        {
            var underlyingType = argumentDef.Type.GetUnderlyingType();

            var argument = BuildArgument(
                argumentDef,
                new TypeInfo(argumentDef.Type, underlyingType),
                isInterceptorOption);

            argument.Services.AddOrUpdate(argumentDef);
            if (argumentDef.CustomAttributes is ParameterInfo param)
            {
                argument.Services.Add(param);
            }
            else if (argumentDef.CustomAttributes is PropertyInfo prop)
            {
                argument.Services.Add(prop);
            }

            var typeDescriptor = appConfig.AppSettings.ArgumentTypeDescriptors.GetDescriptorOrThrow(underlyingType);

            argument.TypeInfo.DisplayName = typeDescriptor.GetDisplayName(argument);

            if (typeDescriptor is IAllowedValuesTypeDescriptor allowedValuesTypeDescriptor)
            {
                argument.AllowedValues = allowedValuesTypeDescriptor.GetAllowedValues(argument).ToReadOnlyCollection();
            }
            return(argument);
        }
        internal static BooleanMode?GetBooleanMode(
            this IArgumentDef argumentDef, BooleanMode defaultBooleanMode)
        {
            if (argumentDef.Type != typeof(bool) && argumentDef.Type != typeof(bool?))
            {
                return(null);
            }

            if (argumentDef.CommandNodeType == CommandNodeType.Operand)
            {
                return(BooleanMode.Explicit);
            }

            OptionAttribute?optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>();

            if (optionAttr?.BooleanModeAsNullable == null)
            {
                return(defaultBooleanMode);
            }

            return(argumentDef.Type.GetUnderlyingType() == typeof(bool)
                ? optionAttr.BooleanMode
                : throw new InvalidConfigurationException(
                       $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}"));
        }
        // end-snippet

        internal static IArgumentArity Default(IArgumentDef argumentDef)
        {
            return(Default(
                       argumentDef.Type,
                       argumentDef.IsOptional,
                       argumentDef.HasDefaultValue,
                       argumentDef.BooleanMode));
        }
Esempio n. 4
0
        private static IArgument BuildArgument(IArgumentDef argumentDef,
                                               Command parent,
                                               AppConfig appConfig,
                                               TypeInfo typeInfo,
                                               bool isInterceptorOption)
        {
            var defaultValue = argumentDef.HasDefaultValue ? argumentDef.DefaultValue : null;

            if (argumentDef.CommandNodeType == CommandNodeType.Operand)
            {
                var operandAttr = argumentDef.CustomAttributes.GetCustomAttribute <OperandAttribute>()
                                  ?? (INameAndDescription)argumentDef.CustomAttributes.GetCustomAttribute <ArgumentAttribute>();
                return(new Operand(
                           argumentDef.Name,
                           parent,
                           typeInfo,
                           ArgumentArity.Default(argumentDef.Type, argumentDef.HasDefaultValue, BooleanMode.Explicit),
                           argumentDef.SourcePath,
                           customAttributes: argumentDef.CustomAttributes,
                           argumentDef.ValueProxy)
                {
                    Description = operandAttr?.Description,
                    DefaultValue = defaultValue
                });
            }

            if (argumentDef.CommandNodeType == CommandNodeType.Option)
            {
                var optionAttr    = argumentDef.CustomAttributes.GetCustomAttribute <OptionAttribute>();
                var booleanMode   = GetOptionBooleanMode(argumentDef, appConfig.AppSettings.BooleanMode, optionAttr);
                var argumentArity = ArgumentArity.Default(argumentDef.Type, argumentDef.HasDefaultValue, booleanMode);

                var assignOnlyToExecutableSubcommands = optionAttr?.AssignToExecutableSubcommands ?? false;
                isInterceptorOption = isInterceptorOption && !assignOnlyToExecutableSubcommands;

                var longName = optionAttr?.ShortName != null
                    ? optionAttr?.LongName
                    : (optionAttr?.LongName ?? argumentDef.Name);
                return(new Option(
                           longName,
                           ParseShortName(argumentDef, optionAttr?.ShortName),
                           parent,
                           typeInfo,
                           argumentArity,
                           definitionSource: argumentDef.SourcePath,
                           customAttributes: argumentDef.CustomAttributes,
                           isInterceptorOption: isInterceptorOption,
                           assignToExecutableSubcommands: assignOnlyToExecutableSubcommands,
                           valueProxy: argumentDef.ValueProxy)
                {
                    Description = optionAttr?.Description,
                    DefaultValue = defaultValue
                });
            }

            throw new ArgumentOutOfRangeException($"Unknown argument type: {argumentDef.CommandNodeType}");
        }
        internal static char?GetSplitChar(this IArgumentDef argumentDef)
        {
            OptionAttribute?optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>();

            return(optionAttr?.SplitAsNullable is null
                ? null
                : argumentDef.Type.IsNonStringEnumerable()
                    ? optionAttr.SplitAsNullable
                    : throw new InvalidConfigurationException(
                       $"Split can only be specified for IEnumerable<T> types. {argumentDef.SourcePath} is type {argumentDef.Type}"));
        }
        private static BooleanMode GetOptionBooleanMode(
            IArgumentDef argumentDef, BooleanMode appBooleanMode, OptionAttribute optionAttr)
        {
            if (optionAttr == null || optionAttr.BooleanMode == BooleanMode.Unknown)
            {
                return(appBooleanMode);
            }

            return(argumentDef.Type.GetUnderlyingType() == typeof(bool)
                ? optionAttr.BooleanMode
                : throw new AppRunnerException(
                       $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}"));
        }
Esempio n. 7
0
        private static BooleanMode GetOptionBooleanMode(
            IArgumentDef argumentDef, BooleanMode defaultBooleanMode, OptionAttribute?optionAttr)
        {
            if (optionAttr?.BooleanModeAsNullable == null)
            {
                return(defaultBooleanMode);
            }

            return(argumentDef.Type.GetUnderlyingType() == typeof(bool)
                ? optionAttr.BooleanMode
                : throw new InvalidConfigurationException(
                       $"BooleanMode is set to `{optionAttr.BooleanMode}` for a non boolean type. {argumentDef}"));
        }
Esempio n. 8
0
        private static string?ParseLongName(IArgumentDef argumentDef, OptionAttribute?optionAttr)
        {
            if (optionAttr == null)
            {
                return(argumentDef.Name);
            }

            if (optionAttr.LongName != null)
            {
                return(optionAttr.LongName);
            }

            return(optionAttr.NoLongName ? null : argumentDef.Name);
        }
        private static IArgument BuildArgument(IArgumentDef argumentDef, TypeInfo typeInfo, bool isInterceptorOption)
        {
            var argumentDefault = argumentDef.HasDefaultValue && !argumentDef.DefaultValue.IsNullValue()
                ? new ArgumentDefault($"app.{argumentDef.ArgumentDefType}", argumentDef.SourcePath, argumentDef.DefaultValue !)
                : null;

            if (argumentDef.CommandNodeType == CommandNodeType.Operand)
            {
                var operandAttr = argumentDef.GetCustomAttribute <OperandAttribute>();
                return(new Operand(
                           argumentDef.Name,
                           typeInfo,
                           argumentDef.Arity,
                           argumentDef.BooleanMode,
                           argumentDef.SourcePath,
                           customAttributes: argumentDef.CustomAttributes,
                           argumentDef.ValueProxy)
                {
                    Description = JoinFromAttribute(argumentDef, nameof(operandAttr.Description), operandAttr?.Description, operandAttr?.DescriptionLines),
                    Default = argumentDefault
                });
            }

            if (argumentDef.CommandNodeType == CommandNodeType.Option)
            {
                var optionAttr = argumentDef.GetCustomAttribute <OptionAttribute>();
                var assignOnlyToExecutableSubcommands = optionAttr?.AssignToExecutableSubcommands ?? false;
                isInterceptorOption = isInterceptorOption && !assignOnlyToExecutableSubcommands;

                return(new Option(
                           ParseLongName(argumentDef, optionAttr),
                           optionAttr?.ShortName,
                           typeInfo,
                           argumentDef.Arity,
                           argumentDef.BooleanMode,
                           definitionSource: argumentDef.SourcePath,
                           customAttributes: argumentDef.CustomAttributes,
                           isInterceptorOption: isInterceptorOption,
                           assignToExecutableSubcommands: assignOnlyToExecutableSubcommands,
                           valueProxy: argumentDef.ValueProxy)
                {
                    Description = JoinFromAttribute(argumentDef, nameof(optionAttr.Description), optionAttr?.Description, optionAttr?.DescriptionLines),
                    Split = argumentDef.Split,
                    Default = argumentDefault
                });
            }

            throw new ArgumentOutOfRangeException($"Unknown argument type: {argumentDef.CommandNodeType}");
        }
        private static char?ParseShortName(IArgumentDef argumentDef, string shortNameAsString)
        {
            if (shortNameAsString.IsNullOrWhitespace())
            {
                return(null);
            }

            if (shortNameAsString.Length > 1)
            {
                throw new ArgumentException($"Short name must be a single character: {shortNameAsString} {argumentDef}",
                                            nameof(shortNameAsString));
            }

            return(shortNameAsString.Single());
        }
Esempio n. 11
0
        private static IArgument ToArgument(this IArgumentDef argumentDef, AppConfig appConfig, bool isInterceptorOption)
        {
            var underlyingType = argumentDef.Type.GetUnderlyingType();

            var argument = BuildArgument(
                argumentDef,
                appConfig,
                new TypeInfo(argumentDef.Type, underlyingType),
                isInterceptorOption);

            argumentDef.Argument = argument;
            argument.Services.AddOrUpdate(argumentDef);

            var typeDescriptor = appConfig.AppSettings.ArgumentTypeDescriptors.GetDescriptorOrThrow(underlyingType);

            argument.TypeInfo.DisplayName = typeDescriptor.GetDisplayName(argument);

            if (typeDescriptor is IAllowedValuesTypeDescriptor allowedValuesTypeDescriptor)
            {
                argument.AllowedValues = allowedValuesTypeDescriptor.GetAllowedValues(argument).ToReadOnlyCollection();
            }
            return(argument);
        }