Refactor CommandInputParser

This commit is contained in:
Alexey Golub
2019-08-19 21:51:06 +03:00
parent e652f9bda4
commit 4b98dbf51f
3 changed files with 33 additions and 46 deletions

View File

@@ -16,6 +16,12 @@ namespace CliFx.Models
public static CommandSchema FindByName(this IReadOnlyList<CommandSchema> commandSchemas, string commandName) public static CommandSchema FindByName(this IReadOnlyList<CommandSchema> commandSchemas, string commandName)
{ {
commandSchemas.GuardNotNull(nameof(commandSchemas)); commandSchemas.GuardNotNull(nameof(commandSchemas));
// If looking for default command, don't compare names directly
// ...because null and empty are both valid names for default command
if (commandName.IsNullOrWhiteSpace())
return commandSchemas.FirstOrDefault(c => c.IsDefault());
return commandSchemas.FirstOrDefault(c => string.Equals(c.Name, commandName, StringComparison.OrdinalIgnoreCase)); return commandSchemas.FirstOrDefault(c => string.Equals(c.Name, commandName, StringComparison.OrdinalIgnoreCase));
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using CliFx.Internal; using CliFx.Internal;
using CliFx.Models; using CliFx.Models;
@@ -16,75 +17,55 @@ namespace CliFx.Services
{ {
commandLineArguments.GuardNotNull(nameof(commandLineArguments)); commandLineArguments.GuardNotNull(nameof(commandLineArguments));
// Initialize command name placeholder var commandNameBuilder = new StringBuilder();
string commandName = null; var optionsDic = new Dictionary<string, List<string>>();
// Initialize options var lastOptionAlias = "";
var rawOptions = new Dictionary<string, List<string>>();
// Keep track of the last option's name
string optionName = null;
// Loop through all arguments
var encounteredFirstOption = false;
foreach (var commandLineArgument in commandLineArguments) foreach (var commandLineArgument in commandLineArguments)
{ {
// Option name // Encountered option name
if (commandLineArgument.StartsWith("--", StringComparison.OrdinalIgnoreCase)) if (commandLineArgument.StartsWith("--", StringComparison.OrdinalIgnoreCase))
{ {
// Extract option name (skip 2 chars) // Extract option alias
optionName = commandLineArgument.Substring(2); lastOptionAlias = commandLineArgument.Substring(2);
if (rawOptions.GetValueOrDefault(optionName) == null) if (!optionsDic.ContainsKey(lastOptionAlias))
rawOptions[optionName] = new List<string>(); optionsDic[lastOptionAlias] = new List<string>();
encounteredFirstOption = true;
} }
// Short option name // Encountered short option name or multiple thereof
else if (commandLineArgument.StartsWith("-", StringComparison.OrdinalIgnoreCase) && commandLineArgument.Length == 2)
{
// Extract option name (skip 1 char)
optionName = commandLineArgument.Substring(1);
if (rawOptions.GetValueOrDefault(optionName) == null)
rawOptions[optionName] = new List<string>();
encounteredFirstOption = true;
}
// Multiple stacked short options
else if (commandLineArgument.StartsWith("-", StringComparison.OrdinalIgnoreCase)) else if (commandLineArgument.StartsWith("-", StringComparison.OrdinalIgnoreCase))
{ {
// Handle stacked options
foreach (var c in commandLineArgument.Substring(1)) foreach (var c in commandLineArgument.Substring(1))
{ {
optionName = c.AsString(); // Extract option alias
lastOptionAlias = c.AsString();
if (rawOptions.GetValueOrDefault(optionName) == null) if (!optionsDic.ContainsKey(lastOptionAlias))
rawOptions[optionName] = new List<string>(); optionsDic[lastOptionAlias] = new List<string>();
} }
encounteredFirstOption = true;
} }
// Command name // Encountered command name or part thereof
else if (!encounteredFirstOption) else if (lastOptionAlias.IsNullOrWhiteSpace())
{ {
if (commandName.IsNullOrWhiteSpace()) commandNameBuilder.AppendIfNotEmpty(' ');
commandName = commandLineArgument; commandNameBuilder.Append(commandLineArgument);
else
commandName += " " + commandLineArgument;
} }
// Option value // Encountered option value
else if (!optionName.IsNullOrWhiteSpace()) else if (!lastOptionAlias.IsNullOrWhiteSpace())
{ {
// ReSharper disable once AssignNullToNotNullAttribute optionsDic[lastOptionAlias].Add(commandLineArgument);
rawOptions[optionName].Add(commandLineArgument);
} }
} }
return new CommandInput(commandName, rawOptions.Select(p => new CommandOptionInput(p.Key, p.Value)).ToArray()); var commandName = commandNameBuilder.Length > 0 ? commandNameBuilder.ToString() : null;
var options = optionsDic.Select(p => new CommandOptionInput(p.Key, p.Value)).ToArray();
return new CommandInput(commandName, options);
} }
} }
} }

View File

@@ -18,7 +18,7 @@ namespace CliFx.Services
resolver.GuardNotNull(nameof(resolver)); resolver.GuardNotNull(nameof(resolver));
commandType.GuardNotNull(nameof(commandType)); commandType.GuardNotNull(nameof(commandType));
return resolver.GetCommandSchemas(new[] {commandType}).First(); return resolver.GetCommandSchemas(new[] {commandType}).Single();
} }
/// <summary> /// <summary>