Remove option groups

This commit is contained in:
Alexey Golub
2019-08-17 19:31:09 +03:00
parent fc1568ce20
commit e5bbda5892
10 changed files with 36 additions and 86 deletions

View File

@@ -18,4 +18,4 @@ namespace CliFx.Benchmarks.Commands
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
}

View File

@@ -4,7 +4,7 @@ using CliFx.Services;
namespace CliFx.Demo.Internal
{
internal static class ConsoleExtensions
internal static class Extensions
{
public static void RenderBook(this IConsole console, Book book)
{

View File

@@ -23,9 +23,6 @@ namespace CliFx.Tests
[CommandOption("str", 's')]
public string StringOption { get; set; } = "foo bar";
[CommandOption("bool", 'b', GroupName = "other-group")]
public bool BoolOption { get; set; }
public Task ExecuteAsync(IConsole console) => Task.CompletedTask;
}
}
@@ -59,41 +56,6 @@ namespace CliFx.Tests
}),
new TestCommand {IntOption = 13}
);
yield return new TestCaseData(
new CommandInput(new[]
{
new CommandOptionInput("bool")
}),
new TestCommand {BoolOption = true}
);
yield return new TestCaseData(
new CommandInput(new[]
{
new CommandOptionInput("b")
}),
new TestCommand {BoolOption = true}
);
yield return new TestCaseData(
new CommandInput(new[]
{
new CommandOptionInput("bool"),
new CommandOptionInput("str", "hello world")
}),
new TestCommand {BoolOption = true}
);
yield return new TestCaseData(
new CommandInput(new[]
{
new CommandOptionInput("int", "13"),
new CommandOptionInput("str", "hello world"),
new CommandOptionInput("bool")
}),
new TestCommand {IntOption = 13, StringOption = "hello world"}
);
}
private static IEnumerable<TestCaseData> GetTestCases_InitializeCommand_IsRequired()

View File

@@ -17,7 +17,7 @@ namespace CliFx.Tests
[SuppressMessage("ReSharper", "MemberCanBePrivate.Local")]
private class TestCommand : ICommand
{
[CommandOption("option-a", 'a', GroupName = "Group 1")]
[CommandOption("option-a", 'a')]
public int OptionA { get; set; }
[CommandOption("option-b", IsRequired = true)]
@@ -41,11 +41,11 @@ namespace CliFx.Tests
new[]
{
new CommandOptionSchema(typeof(TestCommand).GetProperty(nameof(TestCommand.OptionA)),
"option-a", 'a', "Group 1", false, null),
"option-a", 'a', false, null),
new CommandOptionSchema(typeof(TestCommand).GetProperty(nameof(TestCommand.OptionB)),
"option-b", null, null, true, null),
"option-b", null, true, null),
new CommandOptionSchema(typeof(TestCommand).GetProperty(nameof(TestCommand.OptionC)),
"option-c", null, null, false, "Option C description")
"option-c", null, false, "Option C description")
})
);
}

View File

@@ -18,11 +18,6 @@ namespace CliFx.Attributes
/// </summary>
public char? ShortName { get; }
/// <summary>
/// Option group name.
/// </summary>
public string GroupName { get; set; }
/// <summary>
/// Whether an option is required.
/// </summary>

View File

@@ -24,11 +24,6 @@ namespace CliFx.Models
/// </summary>
public char? ShortName { get; }
/// <summary>
/// Option group name.
/// </summary>
public string GroupName { get; }
/// <summary>
/// Whether an option is required.
/// </summary>
@@ -42,14 +37,12 @@ namespace CliFx.Models
/// <summary>
/// Initializes an instance of <see cref="CommandOptionSchema"/>.
/// </summary>
public CommandOptionSchema(PropertyInfo property, string name, char? shortName,
string groupName, bool isRequired, string description)
public CommandOptionSchema(PropertyInfo property, string name, char? shortName, bool isRequired, string description)
{
Property = property; // can be null
Name = name; // can be null
ShortName = shortName; // can be null
IsRequired = isRequired;
GroupName = groupName; // can be null
Description = description; // can be null
}

View File

@@ -107,8 +107,7 @@ namespace CliFx.Models
// Compare against short name. Case is NOT ignored.
var matchesByShortName =
optionSchema.ShortName != null &&
alias.Length == 1 &&
alias[0] == optionSchema.ShortName;
alias.Length == 1 && alias[0] == optionSchema.ShortName;
if (matchesByName || matchesByShortName)
return optionSchema;
@@ -116,5 +115,21 @@ namespace CliFx.Models
return null;
}
/// <summary>
/// Gets valid aliases for the option.
/// </summary>
public static IReadOnlyList<string> GetAliases(this CommandOptionSchema optionSchema)
{
var result = new List<string>(2);
if (!optionSchema.Name.IsNullOrWhiteSpace())
result.Add(optionSchema.Name);
if (optionSchema.ShortName != null)
result.Add(optionSchema.ShortName.Value.AsString());
return result;
}
}
}

View File

@@ -154,10 +154,10 @@ namespace CliFx.Services
var options = new List<CommandOptionSchema>();
options.AddRange(source.TargetCommandSchema.Options);
options.Add(new CommandOptionSchema(null, "help", 'h', null, false, "Shows help text."));
options.Add(new CommandOptionSchema(null, "help", 'h', false, "Shows help text."));
if (source.TargetCommandSchema.IsDefault())
options.Add(new CommandOptionSchema(null, "version", null, null, false, "Shows application version."));
options.Add(new CommandOptionSchema(null, "version", null, false, "Shows application version."));
// Margin
if (!IsEmpty())

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using CliFx.Exceptions;
using CliFx.Internal;
using CliFx.Models;
@@ -37,10 +35,9 @@ namespace CliFx.Services
schema.GuardNotNull(nameof(schema));
input.GuardNotNull(nameof(input));
var unsetRequiredOptions = schema.Options.Where(o => o.IsRequired).ToList();
// Set command options
var isGroupNameDetected = false;
var groupName = default(string);
var properties = new HashSet<CommandOptionSchema>();
foreach (var option in input.Options)
{
var optionSchema = schema.Options.FindByAlias(option.Alias);
@@ -48,30 +45,19 @@ namespace CliFx.Services
if (optionSchema == null)
continue;
if (isGroupNameDetected && !string.Equals(groupName, optionSchema.GroupName, StringComparison.OrdinalIgnoreCase))
continue;
if (!isGroupNameDetected)
{
groupName = optionSchema.GroupName;
isGroupNameDetected = true;
}
var convertedValue = _commandOptionInputConverter.ConvertOption(option, optionSchema.Property.PropertyType);
optionSchema.Property.SetValue(command, convertedValue);
properties.Add(optionSchema);
if (optionSchema.IsRequired)
unsetRequiredOptions.Remove(optionSchema);
}
var unsetRequiredOptions = schema.Options
.Except(properties)
.Where(p => p.IsRequired)
.Where(p => string.Equals(p.GroupName, groupName, StringComparison.OrdinalIgnoreCase))
.ToArray();
// Throw if any of the required options were not set
if (unsetRequiredOptions.Any())
throw new MissingCommandOptionException(
$"Can't resolve command because one or more required properties were not set: {unsetRequiredOptions.Select(p => p.Name).JoinToString(", ")}");
{
var unsetRequiredOptionNames = unsetRequiredOptions.Select(o => o.GetAliases().FirstOrDefault()).JoinToString(", ");
throw new MissingCommandOptionException($"One or more required options were not set: {unsetRequiredOptionNames}.");
}
}
}
}

View File

@@ -22,7 +22,6 @@ namespace CliFx.Services
return new CommandOptionSchema(optionProperty,
attribute.Name,
attribute.ShortName,
attribute.GroupName,
attribute.IsRequired,
attribute.Description);
}