Allow using -? as a shorthand for -h

Given that it's quite a common switch and extremely unlikely to be already in use for something else, we can just consider it to be the same as having entered `-h` as an arg.

This adds the `?` as a valid option character name.

Fixes #1547
This commit is contained in:
Daniel Cazzulino 2024-05-17 18:08:29 -03:00 committed by Patrik Svensson
parent 0e2ed511a5
commit 5c87d7fa04
6 changed files with 72 additions and 3 deletions

View File

@ -86,7 +86,7 @@ internal static class TemplateParser
foreach (var character in token.Value)
{
if (!char.IsLetterOrDigit(character) && character != '-' && character != '_')
if (!char.IsLetterOrDigit(character) && character != '-' && character != '_' && character != '?')
{
throw CommandTemplateException.InvalidCharacterInOptionName(template, token, character);
}

View File

@ -21,7 +21,7 @@ internal class CommandTreeParser
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_parsingMode = parsingMode ?? _configuration.ParsingMode;
_help = new CommandOptionAttribute("-h|--help");
_help = new CommandOptionAttribute("-?|-h|--help");
_convertFlagsToRemainingArguments = convertFlagsToRemainingArguments ?? false;
CaseSensitivity = caseSensitivity;

View File

@ -176,7 +176,7 @@ internal static class CommandTreeTokenizer
break;
}
if (char.IsLetter(current))
if (char.IsLetter(current) || current is '?')
{
context.AddRemaining(current);
reader.Read(); // Consume

View File

@ -0,0 +1,10 @@
USAGE:
myapp [OPTIONS] <COMMAND>
OPTIONS:
-h, --help Prints help information
COMMANDS:
dog <AGE> The dog command
horse The horse command
giraffe <LENGTH> The giraffe command

View File

@ -0,0 +1,17 @@
DESCRIPTION:
The horse command.
USAGE:
myapp horse [LEGS] [OPTIONS]
ARGUMENTS:
[LEGS] The number of legs
OPTIONS:
DEFAULT
-h, --help Prints help information
-a, --alive Indicates whether or not the animal is alive
-n, --name <VALUE>
-d, --day <MON|TUE>
--file food.txt
--directory

View File

@ -28,6 +28,27 @@ public sealed partial class CommandAppTests
return Verifier.Verify(result.Output);
}
[Fact]
[Expectation("Root", "QuestionMark")]
public Task Should_Output_Root_Correctly_QuestionMark()
{
// Given
var fixture = new CommandAppTester();
fixture.Configure(configurator =>
{
configurator.SetApplicationName("myapp");
configurator.AddCommand<DogCommand>("dog");
configurator.AddCommand<HorseCommand>("horse");
configurator.AddCommand<GiraffeCommand>("giraffe");
});
// When
var result = fixture.Run("-?");
// Then
return Verifier.Verify(result.Output);
}
[Fact]
[Expectation("Root_Command")]
public Task Should_Output_Root_Command_Correctly()
@ -49,6 +70,27 @@ public sealed partial class CommandAppTests
return Verifier.Verify(result.Output);
}
[Fact]
[Expectation("Root_Command", "QuestionMark")]
public Task Should_Output_Root_Command_Correctly_QuestionMark()
{
// Given
var fixture = new CommandAppTester();
fixture.Configure(configurator =>
{
configurator.SetApplicationName("myapp");
configurator.AddCommand<DogCommand>("dog");
configurator.AddCommand<HorseCommand>("horse");
configurator.AddCommand<GiraffeCommand>("giraffe");
});
// When
var result = fixture.Run("horse", "-?");
// Then
return Verifier.Verify(result.Output);
}
[Fact]
[Expectation("Hidden_Commands")]
public Task Should_Skip_Hidden_Commands()