mirror of
				https://github.com/nsnail/spectre.console.git
				synced 2025-11-04 10:35:27 +08:00 
			
		
		
		
	Show help for default command (#953)
Shows help if the default command was called without any arguments but has required arguments. This way it does not hinder execution of a default command without any required arguments. When called without args: - Default command with required params -> Show help - Default command with required params and additional commands -> Show help including additional commands - Default command without required params -> Execute command
This commit is contained in:
		@@ -66,6 +66,14 @@ internal sealed class CommandExecutor
 | 
			
		||||
            return leaf.ShowHelp ? 0 : 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Is this the default and is it called without arguments when there are required arguments?
 | 
			
		||||
        if (leaf.Command.IsDefaultCommand && args.Count() == 0 && leaf.Command.Parameters.Any(p => p.Required))
 | 
			
		||||
        {
 | 
			
		||||
            // Display help for default command.
 | 
			
		||||
            configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command));
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Register the arguments with the container.
 | 
			
		||||
        _registrar.RegisterInstance(typeof(IRemainingArguments), parsedResult.Remaining);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,17 @@
 | 
			
		||||
using Spectre.Console;
 | 
			
		||||
 | 
			
		||||
public class GreeterCommand : Command<OptionalArgumentWithDefaultValueSettings>
 | 
			
		||||
{
 | 
			
		||||
    private readonly IAnsiConsole _console;
 | 
			
		||||
 | 
			
		||||
    public GreeterCommand(IAnsiConsole console)
 | 
			
		||||
    {
 | 
			
		||||
        _console = console;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public override int Execute([NotNull] CommandContext context, [NotNull] OptionalArgumentWithDefaultValueSettings settings)
 | 
			
		||||
    {
 | 
			
		||||
        _console.WriteLine(settings.Greeting);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,16 @@
 | 
			
		||||
DESCRIPTION:
 | 
			
		||||
The lion command.
 | 
			
		||||
 | 
			
		||||
USAGE:
 | 
			
		||||
    myapp <TEETH> [LEGS] [OPTIONS]
 | 
			
		||||
 | 
			
		||||
ARGUMENTS:
 | 
			
		||||
    <TEETH>    The number of teeth the lion has
 | 
			
		||||
    [LEGS]     The number of legs
 | 
			
		||||
 | 
			
		||||
OPTIONS:
 | 
			
		||||
    -h, --help               Prints help information
 | 
			
		||||
    -a, --alive              Indicates whether or not the animal is alive
 | 
			
		||||
    -n, --name <VALUE>
 | 
			
		||||
        --agility <VALUE>    The agility between 0 and 100
 | 
			
		||||
    -c <CHILDREN>            The number of children the lion has
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
DESCRIPTION:
 | 
			
		||||
The lion command.
 | 
			
		||||
 | 
			
		||||
USAGE:
 | 
			
		||||
    myapp <TEETH> [LEGS] [OPTIONS]
 | 
			
		||||
 | 
			
		||||
ARGUMENTS:
 | 
			
		||||
    <TEETH>    The number of teeth the lion has
 | 
			
		||||
    [LEGS]     The number of legs
 | 
			
		||||
 | 
			
		||||
OPTIONS:
 | 
			
		||||
    -h, --help               Prints help information
 | 
			
		||||
    -a, --alive              Indicates whether or not the animal is alive
 | 
			
		||||
    -n, --name <VALUE>
 | 
			
		||||
        --agility <VALUE>    The agility between 0 and 100
 | 
			
		||||
    -c <CHILDREN>            The number of children the lion has
 | 
			
		||||
 | 
			
		||||
COMMANDS:
 | 
			
		||||
    giraffe <LENGTH>    The giraffe command
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
Hello World
 | 
			
		||||
@@ -29,4 +29,15 @@
 | 
			
		||||
    <ProjectReference Include="..\..\src\Spectre.Console\Spectre.Console.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Update="Expectations\Help\Default_Without_Args_Additional.Output.verified.txt">
 | 
			
		||||
      <ParentFile>$([System.String]::Copy('%(FileName)').Split('.')[0])</ParentFile>
 | 
			
		||||
      <DependentUpon>%(ParentFile).cs</DependentUpon>
 | 
			
		||||
    </None>
 | 
			
		||||
    <None Update="Expectations\Help\Greeter_Default.Output.verified.txt">
 | 
			
		||||
      <ParentFile>$([System.String]::Copy('%(FileName)').Split('.')[0])</ParentFile>
 | 
			
		||||
      <DependentUpon>%(ParentFile).cs</DependentUpon>
 | 
			
		||||
    </None>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -141,6 +141,64 @@ public sealed partial class CommandAppTests
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Default_Without_Args")]
 | 
			
		||||
        public Task Should_Output_Default_Command_When_Command_Has_Required_Parameters_And_Is_Called_Without_Args()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<LionCommand>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Default_Without_Args_Additional")]
 | 
			
		||||
        public Task Should_Output_Default_Command_And_Additional_Commands_When_Default_Command_Has_Required_Parameters_And_Is_Called_Without_Args()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<LionCommand>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
                configurator.AddCommand<GiraffeCommand>("giraffe");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("Greeter_Default")]
 | 
			
		||||
        public Task Should_Not_Output_Default_Command_When_Command_Has_No_Required_Parameters_And_Is_Called_Without_Args()
 | 
			
		||||
        {
 | 
			
		||||
            // Given
 | 
			
		||||
            var fixture = new CommandAppTester();
 | 
			
		||||
            fixture.SetDefaultCommand<GreeterCommand>();
 | 
			
		||||
            fixture.Configure(configurator =>
 | 
			
		||||
            {
 | 
			
		||||
                configurator.SetApplicationName("myapp");
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // When
 | 
			
		||||
            var result = fixture.Run();
 | 
			
		||||
 | 
			
		||||
            // Then
 | 
			
		||||
            return Verifier.Verify(result.Output);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        [Expectation("RootExamples")]
 | 
			
		||||
        public Task Should_Output_Root_Examples_Defined_On_Root()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user