mirror of
https://github.com/Tyrrrz/CliFx.git
synced 2025-10-25 15:19:17 +00:00
Refactor CommandInputParser
This commit is contained in:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user