public static TypinException CannotConvertMultipleValuesToNonScalar(CommandOptionSchema option, IReadOnlyList <string> values)
        {
            string message = $@"
Option {option} expects a single value, but provided with multiple:
{values.Select(v => v.Quote()).JoinToString(' ')}";

            return(new TypinException(message.Trim()));
        }
 public static TypinException CannotConvertMultipleValuesToNonScalar(ArgumentSchema argument, IReadOnlyList <string> values)
 {
     return(argument switch
     {
         CommandParameterSchema parameter => CannotConvertMultipleValuesToNonScalar(parameter, values),
         CommandOptionSchema option => CannotConvertMultipleValuesToNonScalar(option, values),
         _ => throw new ArgumentOutOfRangeException(nameof(argument))
     });
        private IReadOnlyList <CommandOptionSchema> GetCommandOptionSchemas(Type commandType)
        {
            var result = new List <CommandOptionSchema>();

            foreach (var property in commandType.GetProperties())
            {
                var attribute = property.GetCustomAttribute <CommandOptionAttribute>();

                // If an attribute is not set, then it's not an option so we just skip it
                if (attribute == null)
                {
                    continue;
                }

                // Build option schema
                var optionSchema = new CommandOptionSchema(property,
                                                           attribute.Name,
                                                           attribute.ShortName,
                                                           attribute.IsRequired,
                                                           attribute.Description,
                                                           attribute.EnvironmentVariableName);

                // Make sure there are no other options with the same name
                var existingOptionWithSameName = result
                                                 .Where(o => !string.IsNullOrWhiteSpace(o.Name))
                                                 .FirstOrDefault(o => string.Equals(o.Name, optionSchema.Name, StringComparison.OrdinalIgnoreCase));

                if (existingOptionWithSameName != null)
                {
                    throw new CliFxException(
                              $"Command type [{commandType}] has two options that have the same name ({optionSchema.Name}): " +
                              $"[{existingOptionWithSameName.Property}] and [{optionSchema.Property}]. " +
                              "All options in a command need to have unique names (case-insensitive).");
                }

                // Make sure there are no other options with the same short name
                var existingOptionWithSameShortName = result
                                                      .Where(o => o.ShortName != null)
                                                      .FirstOrDefault(o => o.ShortName == optionSchema.ShortName);

                if (existingOptionWithSameShortName != null)
                {
                    throw new CliFxException(
                              $"Command type [{commandType}] has two options that have the same short name ({optionSchema.ShortName}): " +
                              $"[{existingOptionWithSameShortName.Property}] and [{optionSchema.Property}]. " +
                              "All options in a command need to have unique short names (case-sensitive).");
                }

                // Add schema to list
                result.Add(optionSchema);
            }

            return(result);
        }
        /// <inheritdoct />
        public CommandOptionInput GetCommandOptionInputFromEnvironmentVariable(string environmentVariableValue, CommandOptionSchema targetOptionSchema)
        {
            //If the option is not a collection do not split environment variable values
            var optionIsCollection = targetOptionSchema.Property != null && targetOptionSchema.Property.PropertyType.IsCollection();

            if (!optionIsCollection)
            {
                return(new CommandOptionInput(targetOptionSchema.EnvironmentVariableName, environmentVariableValue));
            }

            //If the option is a collection split the values using System separator, empty values are discarded
            var environmentVariableValues = environmentVariableValue.Split(Path.PathSeparator)
                                            .Where(v => !string.IsNullOrWhiteSpace(v))
                                            .ToList();

            return(new CommandOptionInput(targetOptionSchema.EnvironmentVariableName, environmentVariableValues));
        }