Add Write(...), ``WriteLine(...), Read() and ReadLine() extension methods for IConsole (#140)

This commit is contained in:
Oleksii Holub
2024-01-23 23:57:33 +02:00
committed by GitHub
parent 4bdd3ccc6c
commit aee63cb9f2
22 changed files with 161 additions and 122 deletions

View File

@@ -83,7 +83,7 @@ public class SystemConsoleShouldBeAvoidedAnalyzerSpecs
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Hello world"); console.WriteLine("Hello world");
return default; return default;
} }
} }

View File

@@ -9,7 +9,7 @@ using CliFx.Infrastructure;
namespace CliFx.Demo.Commands; namespace CliFx.Demo.Commands;
[Command("book add", Description = "Adds a book to the library.")] [Command("book add", Description = "Adds a book to the library.")]
public partial class BookAddCommand(LibraryProvider libraryProvider) : ICommand public class BookAddCommand(LibraryProvider libraryProvider) : ICommand
{ {
[CommandParameter(0, Name = "title", Description = "Book title.")] [CommandParameter(0, Name = "title", Description = "Book title.")]
public required string Title { get; init; } public required string Title { get; init; }
@@ -18,47 +18,38 @@ public partial class BookAddCommand(LibraryProvider libraryProvider) : ICommand
public required string Author { get; init; } public required string Author { get; init; }
[CommandOption("published", 'p', Description = "Book publish date.")] [CommandOption("published", 'p', Description = "Book publish date.")]
public DateTimeOffset Published { get; init; } = CreateRandomDate(); public DateTimeOffset Published { get; init; } =
new(
Random.Shared.Next(1800, 2020),
Random.Shared.Next(1, 12),
Random.Shared.Next(1, 28),
Random.Shared.Next(1, 23),
Random.Shared.Next(1, 59),
Random.Shared.Next(1, 59),
TimeSpan.Zero
);
[CommandOption("isbn", 'n', Description = "Book ISBN.")] [CommandOption("isbn", 'n', Description = "Book ISBN.")]
public Isbn Isbn { get; init; } = CreateRandomIsbn(); public Isbn Isbn { get; init; } =
new(
Random.Shared.Next(0, 999),
Random.Shared.Next(0, 99),
Random.Shared.Next(0, 99999),
Random.Shared.Next(0, 99),
Random.Shared.Next(0, 9)
);
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
if (libraryProvider.TryGetBook(Title) is not null) if (libraryProvider.TryGetBook(Title) is not null)
throw new CommandException("Book already exists.", 10); throw new CommandException($"Book '{Title}' already exists.", 10);
var book = new Book(Title, Author, Published, Isbn); var book = new Book(Title, Author, Published, Isbn);
libraryProvider.AddBook(book); libraryProvider.AddBook(book);
console.Output.WriteLine("Book added."); console.WriteLine($"Book '{Title}' added.");
console.Output.WriteBook(book); console.WriteBook(book);
return default; return default;
} }
} }
public partial class BookAddCommand
{
private static readonly Random Random = new();
private static DateTimeOffset CreateRandomDate() =>
new(
Random.Next(1800, 2020),
Random.Next(1, 12),
Random.Next(1, 28),
Random.Next(1, 23),
Random.Next(1, 59),
Random.Next(1, 59),
TimeSpan.Zero
);
private static Isbn CreateRandomIsbn() =>
new(
Random.Next(0, 999),
Random.Next(0, 99),
Random.Next(0, 99999),
Random.Next(0, 99),
Random.Next(0, 9)
);
}

View File

@@ -18,9 +18,9 @@ public class BookCommand(LibraryProvider libraryProvider) : ICommand
var book = libraryProvider.TryGetBook(Title); var book = libraryProvider.TryGetBook(Title);
if (book is null) if (book is null)
throw new CommandException("Book not found.", 10); throw new CommandException($"Book '{Title}' not found.", 10);
console.Output.WriteBook(book); console.WriteBook(book);
return default; return default;
} }

View File

@@ -17,11 +17,11 @@ public class BookListCommand(LibraryProvider libraryProvider) : ICommand
{ {
// Add margin // Add margin
if (i != 0) if (i != 0)
console.Output.WriteLine(); console.WriteLine();
// Render book // Render book
var book = library.Books[i]; var book = library.Books[i];
console.Output.WriteBook(book); console.WriteBook(book);
} }
return default; return default;

View File

@@ -17,11 +17,11 @@ public class BookRemoveCommand(LibraryProvider libraryProvider) : ICommand
var book = libraryProvider.TryGetBook(Title); var book = libraryProvider.TryGetBook(Title);
if (book is null) if (book is null)
throw new CommandException("Book not found.", 10); throw new CommandException($"Book '{Title}' not found.", 10);
libraryProvider.RemoveBook(book); libraryProvider.RemoveBook(book);
console.Output.WriteLine($"Book {Title} removed."); console.WriteLine($"Book '{Title}' removed.");
return default; return default;
} }

View File

@@ -33,4 +33,7 @@ internal static class ConsoleExtensions
using (writer.Console.WithForegroundColor(ConsoleColor.White)) using (writer.Console.WithForegroundColor(ConsoleColor.White))
writer.WriteLine(book.Isbn); writer.WriteLine(book.Isbn);
} }
public static void WriteBook(this IConsole console, Book book) =>
console.Output.WriteBook(book);
} }

View File

@@ -12,15 +12,15 @@ public class CancellationTestCommand : ICommand
{ {
try try
{ {
console.Output.WriteLine("Started."); console.WriteLine("Started.");
await Task.Delay(TimeSpan.FromSeconds(3), console.RegisterCancellationHandler()); await Task.Delay(TimeSpan.FromSeconds(3), console.RegisterCancellationHandler());
console.Output.WriteLine("Completed."); console.WriteLine("Completed.");
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
console.Output.WriteLine("Cancelled."); console.WriteLine("Cancelled.");
throw; throw;
} }
} }

View File

@@ -12,8 +12,7 @@ public class EnvironmentTestCommand : ICommand
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine($"Hello {GreetingTarget}!"); console.WriteLine($"Hello {GreetingTarget}!");
return default; return default;
} }
} }

View File

@@ -66,18 +66,18 @@ public class CancellationSpecs(ITestOutputHelper testOutput) : SpecsBase(testOut
{ {
try try
{ {
console.Output.WriteLine("Started."); console.WriteLine("Started.");
await Task.Delay( await Task.Delay(
TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3),
console.RegisterCancellationHandler() console.RegisterCancellationHandler()
); );
console.Output.WriteLine("Completed."); console.WriteLine("Completed.");
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
console.Output.WriteLine("Cancelled."); console.WriteLine("Cancelled.");
throw; throw;
} }
} }

View File

@@ -170,9 +170,9 @@ public class ConsoleSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(console.ReadKey().Key); console.WriteLine(console.ReadKey().Key);
console.Output.WriteLine(console.ReadKey().Key); console.WriteLine(console.ReadKey().Key);
console.Output.WriteLine(console.ReadKey().Key); console.WriteLine(console.ReadKey().Key);
return default; return default;
} }

View File

@@ -25,7 +25,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -62,7 +62,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -105,9 +105,9 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
console.Output.WriteLine("Baz = " + Baz); console.WriteLine("Baz = " + Baz);
return default; return default;
} }
@@ -148,7 +148,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -185,7 +185,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo.ToString(CultureInfo.InvariantCulture)); console.WriteLine(Foo.ToString(CultureInfo.InvariantCulture));
return default; return default;
} }
} }
@@ -225,7 +225,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo.ToString("u", CultureInfo.InvariantCulture)); console.WriteLine(Foo.ToString("u", CultureInfo.InvariantCulture));
return default; return default;
} }
} }
@@ -265,7 +265,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo.ToString(null, CultureInfo.InvariantCulture)); console.WriteLine(Foo.ToString(null, CultureInfo.InvariantCulture));
return default; return default;
} }
} }
@@ -307,7 +307,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine((int) Foo); console.WriteLine((int) Foo);
return default; return default;
} }
} }
@@ -347,8 +347,8 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -391,8 +391,8 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + (int?) Foo); console.WriteLine("Foo = " + (int?) Foo);
console.Output.WriteLine("Bar = " + (int?) Bar); console.WriteLine("Bar = " + (int?) Bar);
return default; return default;
} }
@@ -437,7 +437,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo.Value); console.WriteLine(Foo.Value);
return default; return default;
} }
} }
@@ -497,8 +497,8 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo.Value); console.WriteLine("Foo = " + Foo.Value);
console.Output.WriteLine("Bar = " + Bar.Value); console.WriteLine("Bar = " + Bar.Value);
return default; return default;
} }
@@ -545,7 +545,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -586,7 +586,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -628,7 +628,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -670,7 +670,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -712,7 +712,7 @@ public class ConversionSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutpu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }

View File

@@ -32,8 +32,8 @@ public class EnvironmentSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutp
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
console.Output.WriteLine(Bar); console.WriteLine(Bar);
return default; return default;
} }
@@ -75,7 +75,7 @@ public class EnvironmentSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutp
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -116,7 +116,7 @@ public class EnvironmentSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutp
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }

View File

@@ -26,7 +26,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -63,7 +63,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }
@@ -103,8 +103,8 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -148,8 +148,8 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -193,8 +193,8 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -236,7 +236,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -278,7 +278,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -320,7 +320,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -362,7 +362,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -404,7 +404,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
foreach (var i in Foo) foreach (var i in Foo)
console.Output.WriteLine(i); console.WriteLine(i);
return default; return default;
} }
@@ -448,8 +448,8 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -522,9 +522,9 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + SharedContext.Foo); console.WriteLine("Foo = " + SharedContext.Foo);
console.Output.WriteLine("Bar = " + SharedContext.Bar); console.WriteLine("Bar = " + SharedContext.Bar);
console.Output.WriteLine("Baz = " + Baz); console.WriteLine("Baz = " + Baz);
return default; return default;
} }
@@ -562,7 +562,7 @@ public class OptionBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOu
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(Foo); console.WriteLine(Foo);
return default; return default;
} }
} }

View File

@@ -28,8 +28,8 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }
@@ -76,11 +76,11 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
foreach (var i in Baz) foreach (var i in Baz)
console.Output.WriteLine("Baz = " + i); console.WriteLine("Baz = " + i);
return default; return default;
} }
@@ -198,8 +198,8 @@ public class ParameterBindingSpecs(ITestOutputHelper testOutput) : SpecsBase(tes
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("Foo = " + Foo); console.WriteLine("Foo = " + Foo);
console.Output.WriteLine("Bar = " + Bar); console.WriteLine("Bar = " + Bar);
return default; return default;
} }

View File

@@ -22,7 +22,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("default"); console.WriteLine("default");
return default; return default;
} }
} }
@@ -32,7 +32,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd"); console.WriteLine("cmd");
return default; return default;
} }
} }
@@ -42,7 +42,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd child"); console.WriteLine("cmd child");
return default; return default;
} }
} }
@@ -79,7 +79,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("default"); console.WriteLine("default");
return default; return default;
} }
} }
@@ -89,7 +89,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd"); console.WriteLine("cmd");
return default; return default;
} }
} }
@@ -99,7 +99,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd child"); console.WriteLine("cmd child");
return default; return default;
} }
} }
@@ -133,7 +133,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("default"); console.WriteLine("default");
return default; return default;
} }
} }
@@ -143,7 +143,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd"); console.WriteLine("cmd");
return default; return default;
} }
} }
@@ -153,7 +153,7 @@ public class RoutingSpecs(ITestOutputHelper testOutput) : SpecsBase(testOutput)
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("cmd child"); console.WriteLine("cmd child");
return default; return default;
} }
} }

View File

@@ -24,7 +24,7 @@ public class TypeActivationSpecs(ITestOutputHelper testOutput) : SpecsBase(testO
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("foo"); console.WriteLine("foo");
return default; return default;
} }
} }
@@ -102,7 +102,7 @@ public class TypeActivationSpecs(ITestOutputHelper testOutput) : SpecsBase(testO
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(_foo); console.WriteLine(_foo);
return default; return default;
} }
} }
@@ -144,7 +144,7 @@ public class TypeActivationSpecs(ITestOutputHelper testOutput) : SpecsBase(testO
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine(_foo); console.WriteLine(_foo);
return default; return default;
} }
} }
@@ -195,7 +195,7 @@ public class TypeActivationSpecs(ITestOutputHelper testOutput) : SpecsBase(testO
{ {
public ValueTask ExecuteAsync(IConsole console) public ValueTask ExecuteAsync(IConsole console)
{ {
console.Output.WriteLine("foo"); console.WriteLine("foo");
return default; return default;
} }
} }

View File

@@ -35,7 +35,7 @@ public sealed class CommandOptionAttribute : Attribute
/// </summary> /// </summary>
public CommandOptionAttribute(char shortName) public CommandOptionAttribute(char shortName)
: this(null, (char?)shortName) { } : this(null, (char?)shortName) { }
/// <summary> /// <summary>
/// Option name. /// Option name.
/// </summary> /// </summary>

View File

@@ -88,7 +88,7 @@ public class CliApplication(
// Handle the preview directive // Handle the preview directive
if (IsPreviewModeEnabled(commandInput)) if (IsPreviewModeEnabled(commandInput))
{ {
console.Output.WriteCommandInput(commandInput); console.WriteCommandInput(commandInput);
return 0; return 0;
} }
@@ -125,14 +125,14 @@ public class CliApplication(
// Handle the help option // Handle the help option
if (ShouldShowHelpText(commandSchema, commandInput)) if (ShouldShowHelpText(commandSchema, commandInput))
{ {
console.Output.WriteHelpText(helpContext); console.WriteHelpText(helpContext);
return 0; return 0;
} }
// Handle the version option // Handle the version option
if (ShouldShowVersionText(commandSchema, commandInput)) if (ShouldShowVersionText(commandSchema, commandInput))
{ {
console.Output.WriteLine(Metadata.Version); console.WriteLine(Metadata.Version);
return 0; return 0;
} }
@@ -150,12 +150,12 @@ public class CliApplication(
} }
catch (CliFxException ex) catch (CliFxException ex)
{ {
console.Error.WriteException(ex); console.WriteException(ex);
if (ex.ShowHelp) if (ex.ShowHelp)
{ {
console.Output.WriteLine(); console.WriteLine();
console.Output.WriteHelpText(helpContext); console.WriteHelpText(helpContext);
} }
return ex.ExitCode; return ex.ExitCode;
@@ -195,7 +195,7 @@ public class CliApplication(
// developer, so we don't swallow them in that case. // developer, so we don't swallow them in that case.
catch (Exception ex) when (!Debugger.IsAttached) catch (Exception ex) when (!Debugger.IsAttached)
{ {
console.Error.WriteException(ex); console.WriteException(ex);
return 1; return 1;
} }
} }

View File

@@ -92,4 +92,7 @@ internal static class CommandInputConsoleFormatterExtensions
this ConsoleWriter consoleWriter, this ConsoleWriter consoleWriter,
CommandInput commandInput CommandInput commandInput
) => new CommandInputConsoleFormatter(consoleWriter).WriteCommandInput(commandInput); ) => new CommandInputConsoleFormatter(consoleWriter).WriteCommandInput(commandInput);
public static void WriteCommandInput(this IConsole console, CommandInput commandInput) =>
console.Output.WriteCommandInput(commandInput);
} }

View File

@@ -122,4 +122,7 @@ internal static class ExceptionConsoleFormatterExtensions
{ {
public static void WriteException(this ConsoleWriter consoleWriter, Exception exception) => public static void WriteException(this ConsoleWriter consoleWriter, Exception exception) =>
new ExceptionConsoleFormatter(consoleWriter).WriteException(exception); new ExceptionConsoleFormatter(consoleWriter).WriteException(exception);
public static void WriteException(this IConsole console, Exception exception) =>
console.Error.WriteException(exception);
} }

View File

@@ -458,4 +458,7 @@ internal static class HelpConsoleFormatterExtensions
{ {
public static void WriteHelpText(this ConsoleWriter consoleWriter, HelpContext context) => public static void WriteHelpText(this ConsoleWriter consoleWriter, HelpContext context) =>
new HelpConsoleFormatter(consoleWriter, context).WriteHelpText(); new HelpConsoleFormatter(consoleWriter, context).WriteHelpText();
public static void WriteHelpText(this IConsole console, HelpContext context) =>
console.Output.WriteHelpText(context);
} }

View File

@@ -108,6 +108,43 @@ public interface IConsole
/// </summary> /// </summary>
public static class ConsoleExtensions public static class ConsoleExtensions
{ {
/// <summary>
/// Writes a string to the console's output stream.
/// </summary>
public static void Write(this IConsole console, string? value) => console.Output.Write(value);
/// <summary>
/// Writes an object to the console's output stream.
/// </summary>
public static void Write(this IConsole console, object? value) => console.Output.Write(value);
/// <summary>
/// Writes an empty line to the console's output stream.
/// </summary>
public static void WriteLine(this IConsole console) => console.Output.WriteLine();
/// <summary>
/// Writes a string to the console's output stream, followed by a line terminator.
/// </summary>
public static void WriteLine(this IConsole console, string? value) =>
console.Output.WriteLine(value);
/// <summary>
/// Writes an object to the console's output stream, followed by a line terminator.
/// </summary>
public static void WriteLine(this IConsole console, object? value) =>
console.Output.WriteLine(value);
/// <summary>
/// Reads a single character from the console's input stream.
/// </summary>
public static int Read(this IConsole console) => console.Input.Read();
/// <summary>
/// Reads a line from the console's input stream.
/// </summary>
public static string? ReadLine(this IConsole console) => console.Input.ReadLine();
/// <summary> /// <summary>
/// Sets the specified foreground color and returns an <see cref="IDisposable" /> /// Sets the specified foreground color and returns an <see cref="IDisposable" />
/// that will reset the color back to its previous value upon disposal. /// that will reset the color back to its previous value upon disposal.