diff --git a/src/Spectre.Console.Cli/CommandApp.cs b/src/Spectre.Console.Cli/CommandApp.cs
index 8ea2c63..4882fc0 100644
--- a/src/Spectre.Console.Cli/CommandApp.cs
+++ b/src/Spectre.Console.Cli/CommandApp.cs
@@ -1,3 +1,5 @@
+using Spectre.Console.Cli.Internal.Configuration;
+
namespace Spectre.Console.Cli;
///
@@ -39,10 +41,11 @@ public sealed class CommandApp : ICommandApp
/// Sets the default command.
///
/// The command type.
- public void SetDefaultCommand()
+ /// A that can be used to configure the default command.
+ public DefaultCommandConfigurator SetDefaultCommand()
where TCommand : class, ICommand
{
- GetConfigurator().SetDefaultCommand();
+ return new DefaultCommandConfigurator(GetConfigurator().SetDefaultCommand());
}
///
diff --git a/src/Spectre.Console.Cli/CommandAppOfT.cs b/src/Spectre.Console.Cli/CommandAppOfT.cs
index b4a1287..295011e 100644
--- a/src/Spectre.Console.Cli/CommandAppOfT.cs
+++ b/src/Spectre.Console.Cli/CommandAppOfT.cs
@@ -1,3 +1,5 @@
+using Spectre.Console.Cli.Internal.Configuration;
+
namespace Spectre.Console.Cli;
///
@@ -8,6 +10,7 @@ public sealed class CommandApp : ICommandApp
where TDefaultCommand : class, ICommand
{
private readonly CommandApp _app;
+ private readonly DefaultCommandConfigurator _defaultCommandConfigurator;
///
/// Initializes a new instance of the class.
@@ -16,7 +19,7 @@ public sealed class CommandApp : ICommandApp
public CommandApp(ITypeRegistrar? registrar = null)
{
_app = new CommandApp(registrar);
- _app.GetConfigurator().SetDefaultCommand();
+ _defaultCommandConfigurator = _app.SetDefaultCommand();
}
///
@@ -46,5 +49,32 @@ public sealed class CommandApp : ICommandApp
public Task RunAsync(IEnumerable args)
{
return _app.RunAsync(args);
+ }
+
+ internal Configurator GetConfigurator()
+ {
+ return _app.GetConfigurator();
+ }
+
+ ///
+ /// Sets the description of the default command.
+ ///
+ /// The default command description.
+ /// The same instance so that multiple calls can be chained.
+ public CommandApp WithDescription(string description)
+ {
+ _defaultCommandConfigurator.WithDescription(description);
+ return this;
+ }
+
+ ///
+ /// Sets data that will be passed to the command via the .
+ ///
+ /// The data to pass to the default command.
+ /// The same instance so that multiple calls can be chained.
+ public CommandApp WithData(object data)
+ {
+ _defaultCommandConfigurator.WithData(data);
+ return this;
}
}
\ No newline at end of file
diff --git a/src/Spectre.Console.Cli/Internal/Configuration/Configurator.cs b/src/Spectre.Console.Cli/Internal/Configuration/Configurator.cs
index 746393c..cd1b42d 100644
--- a/src/Spectre.Console.Cli/Internal/Configuration/Configurator.cs
+++ b/src/Spectre.Console.Cli/Internal/Configuration/Configurator.cs
@@ -25,11 +25,12 @@ internal sealed class Configurator : IUnsafeConfigurator, IConfigurator, IConfig
Examples.Add(args);
}
- public void SetDefaultCommand()
+ public ConfiguredCommand SetDefaultCommand()
where TDefaultCommand : class, ICommand
{
DefaultCommand = ConfiguredCommand.FromType(
CliConstants.DefaultCommandName, isDefaultCommand: true);
+ return DefaultCommand;
}
public ICommandConfigurator AddCommand(string name)
diff --git a/src/Spectre.Console.Cli/Internal/Configuration/DefaultCommandConfigurator.cs b/src/Spectre.Console.Cli/Internal/Configuration/DefaultCommandConfigurator.cs
new file mode 100644
index 0000000..a11432b
--- /dev/null
+++ b/src/Spectre.Console.Cli/Internal/Configuration/DefaultCommandConfigurator.cs
@@ -0,0 +1,36 @@
+namespace Spectre.Console.Cli.Internal.Configuration;
+
+///
+/// Fluent configurator for the default command.
+///
+public sealed class DefaultCommandConfigurator
+{
+ private readonly ConfiguredCommand _defaultCommand;
+
+ internal DefaultCommandConfigurator(ConfiguredCommand defaultCommand)
+ {
+ _defaultCommand = defaultCommand;
+ }
+
+ ///
+ /// Sets the description of the default command.
+ ///
+ /// The default command description.
+ /// The same instance so that multiple calls can be chained.
+ public DefaultCommandConfigurator WithDescription(string description)
+ {
+ _defaultCommand.Description = description;
+ return this;
+ }
+
+ ///
+ /// Sets data that will be passed to the command via the .
+ ///
+ /// The data to pass to the default command.
+ /// The same instance so that multiple calls can be chained.
+ public DefaultCommandConfigurator WithData(object data)
+ {
+ _defaultCommand.Data = data;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/src/Spectre.Console.Testing/Cli/CommandAppTester.cs b/src/Spectre.Console.Testing/Cli/CommandAppTester.cs
index 8143e1c..d06ccd4 100644
--- a/src/Spectre.Console.Testing/Cli/CommandAppTester.cs
+++ b/src/Spectre.Console.Testing/Cli/CommandAppTester.cs
@@ -25,11 +25,25 @@ public sealed class CommandAppTester
///
/// Sets the default command.
///
+ /// The optional default command description.
+ /// The optional default command data.
/// The default command type.
- public void SetDefaultCommand()
+ public void SetDefaultCommand(string? description = null, object? data = null)
where T : class, ICommand
{
- _appConfiguration = (app) => app.SetDefaultCommand();
+ _appConfiguration = (app) =>
+ {
+ var defaultCommandBuilder = app.SetDefaultCommand();
+ if (description != null)
+ {
+ defaultCommandBuilder.WithDescription(description);
+ }
+
+ if (data != null)
+ {
+ defaultCommandBuilder.WithData(data);
+ }
+ };
}
///
diff --git a/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.cs b/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.cs
index 9021b3c..2f69a6b 100644
--- a/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.cs
+++ b/test/Spectre.Console.Cli.Tests/Unit/CommandAppTests.cs
@@ -845,30 +845,6 @@ public sealed partial class CommandAppTests
result.Context.ShouldHaveRemainingArgument("foo", values: new[] { (string)null });
}
- [Fact]
- public void Should_Be_Able_To_Set_The_Default_Command()
- {
- // Given
- var app = new CommandAppTester();
- app.SetDefaultCommand();
-
- // When
- var result = app.Run(new[]
- {
- "4", "12", "--good-boy", "--name", "Rufus",
- });
-
- // Then
- result.ExitCode.ShouldBe(0);
- result.Settings.ShouldBeOfType().And(dog =>
- {
- dog.Legs.ShouldBe(4);
- dog.Age.ShouldBe(12);
- dog.GoodBoy.ShouldBe(true);
- dog.Name.ShouldBe("Rufus");
- });
- }
-
[Fact]
public void Should_Set_Command_Name_In_Context()
{
@@ -917,6 +893,66 @@ public sealed partial class CommandAppTests
// Then
result.Context.ShouldNotBeNull();
result.Context.Data.ShouldBe(123);
+ }
+
+ public sealed class Default_Command
+ {
+ [Fact]
+ public void Should_Be_Able_To_Set_The_Default_Command()
+ {
+ // Given
+ var app = new CommandAppTester();
+ app.SetDefaultCommand();
+
+ // When
+ var result = app.Run(new[]
+ {
+ "4", "12", "--good-boy", "--name", "Rufus",
+ });
+
+ // Then
+ result.ExitCode.ShouldBe(0);
+ result.Settings.ShouldBeOfType().And(dog =>
+ {
+ dog.Legs.ShouldBe(4);
+ dog.Age.ShouldBe(12);
+ dog.GoodBoy.ShouldBe(true);
+ dog.Name.ShouldBe("Rufus");
+ });
+ }
+
+ [Fact]
+ public void Should_Set_The_Default_Command_Description_Data_CommandApp()
+ {
+ // Given
+ var app = new CommandApp();
+ app.SetDefaultCommand()
+ .WithDescription("The default command")
+ .WithData(new string[] { "foo", "bar" });
+
+ // When
+
+ // Then
+ app.GetConfigurator().DefaultCommand.ShouldNotBeNull();
+ app.GetConfigurator().DefaultCommand.Description.ShouldBe("The default command");
+ app.GetConfigurator().DefaultCommand.Data.ShouldBe(new string[] { "foo", "bar" });
+ }
+
+ [Fact]
+ public void Should_Set_The_Default_Command_Description_Data_CommandAppOfT()
+ {
+ // Given
+ var app = new CommandApp()
+ .WithDescription("The default command")
+ .WithData(new string[] { "foo", "bar" });
+
+ // When
+
+ // Then
+ app.GetConfigurator().DefaultCommand.ShouldNotBeNull();
+ app.GetConfigurator().DefaultCommand.Description.ShouldBe("The default command");
+ app.GetConfigurator().DefaultCommand.Data.ShouldBe(new string[] { "foo", "bar" });
+ }
}
public sealed class Delegate_Commands
@@ -930,7 +966,7 @@ public sealed partial class CommandAppTests
var app = new CommandApp();
app.Configure(config =>
- {
+ {
config.PropagateExceptions();
config.AddDelegate(
"foo", (context, settings) =>