This exists as an issues but it hasn't yet been resolved - System.CommandLine: Consider optional case insensitive parsing #133
How can we make it case insensitive?
You can achieve thus in about 60 lines of code by writing generic Middleware processor, as ScottArbeit showed here: Scotts Comment and Scotts example code in f#.
Here is a small example in c# which perfectly works: You can call the compiled App and all parameters are working as expected: --version, --VerSion, -v and -V
public class Program {
private static readonly bool CaseInsensitive = true; // Enable case-insensitive parsing
static async Task<int> Main(string[] args) {
var rootCommand2 = new RootCommand("Sample app for System.CommandLine");
// Create the CommandLineBuilder with and add the Middleware
var builder = new CommandLineBuilder(rootCommand2)
// Set option verb & shortcut
.UseVersionOption("--version", "-v")
.AddMiddleware(CaseInsensitiveMiddleware, MiddlewareOrder.ExceptionHandler)
.UseDefaults();
var parser = builder.Build();
return await parser.InvokeAsync(args);
}
public static void CaseInsensitiveMiddleware(InvocationContext context) {
if (!CaseInsensitive) return;
var commandOptions = context.ParseResult.CommandResult.Command.Options
.Concat(context.ParseResult.RootCommandResult.Command.Options);
var allAliases = commandOptions.SelectMany(option => option.Aliases);
string[] GetCorrectTokenCase(string[] tokens) {
var newTokens = new List<string>(tokens.Length);
for (int i = 0; i < tokens.Length; i++) {
var token = tokens[i];
var matchingAlias = allAliases.FirstOrDefault
(alias =>
alias.Equals(token, StringComparison.InvariantCultureIgnoreCase));
if (matchingAlias != null) {
newTokens.Add(matchingAlias);
continue;
}
if (i > 0) {
var previousToken = tokens[i - 1];
var matchingOption = commandOptions.FirstOrDefault
(option =>
option.Aliases.Contains(previousToken, StringComparer.InvariantCultureIgnoreCase));
if (matchingOption != null) {
var completions = matchingOption.GetCompletions()
.Select(completion => completion.InsertText)
.ToArray();
if (completions.Length > 0) {
var matchingCompletion = completions.FirstOrDefault
(completion =>
token.Equals(completion, StringComparison.InvariantCultureIgnoreCase));
newTokens.Add(matchingCompletion ?? token);
}
else {
newTokens.Add(token);
}
}
else {
newTokens.Add(token);
}
}
else {
newTokens.Add(token);
}
}
return newTokens.ToArray();
}
var tokens = context.ParseResult.Tokens.Select(token => token.Value).ToArray();
string[] newTokens;
if (tokens.Length == 0) {
newTokens = Array.Empty<string>();
}
else if (tokens.Length == 1) {
newTokens = new[] { tokens[0].ToLowerInvariant() };
}
else {
if (tokens[0].StartsWith("-")) {
newTokens = tokens;
}
else {
newTokens = new[] { tokens[0].ToLowerInvariant(), tokens[1].ToLowerInvariant() }
.Concat(GetCorrectTokenCase(tokens.Skip(2).ToArray()))
.ToArray();
}
}
context.ParseResult = context.Parser.Parse(newTokens);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With