From 1ea6d27e890737e601b54c413ad315281ac3ce52 Mon Sep 17 00:00:00 2001 From: Michael Fyffe <6224270+TraGicCode@users.noreply.github.com> Date: Thu, 7 May 2026 06:54:27 -0500 Subject: [PATCH 1/2] Add spinners when sending messages --- .../Commands/NsbCommand/SendCommand.cs | 34 +++++++++---- .../Commands/NsbEvent/PublishCommand.cs | 34 +++++++++---- .../Commands/NsbTimeout/SendTimeout.cs | 30 +++++++++--- website/docs/faq/_category_.json | 4 ++ website/docs/faq/faq.md | 48 +++++++++++++++++++ 5 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 website/docs/faq/_category_.json create mode 100644 website/docs/faq/faq.md diff --git a/src/BuslyCLI.Console/Commands/NsbCommand/SendCommand.cs b/src/BuslyCLI.Console/Commands/NsbCommand/SendCommand.cs index 4edb45c..896267e 100644 --- a/src/BuslyCLI.Console/Commands/NsbCommand/SendCommand.cs +++ b/src/BuslyCLI.Console/Commands/NsbCommand/SendCommand.cs @@ -1,18 +1,20 @@ -using System.Text; +using System.Diagnostics; +using System.Text; using BuslyCLI.Config; using BuslyCLI.Infrastructure.Factories; using NServiceBus.Routing; using NServiceBus.Transport; +using Spectre.Console; using Spectre.Console.Cli; namespace BuslyCLI.Commands.NsbCommand; -public class SendCommand(IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand +public class SendCommand(IAnsiConsole console, IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand { protected override async Task ExecuteAsync(CommandContext context, SendCommandSettings settings, CancellationToken cancellationToken) { var config = await nServiceBusConfiguration.GetValidatedConfigurationAsync(settings.Config.Path); - var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); + // TODO: Validate body is valid json/xml var headers = new Dictionary { @@ -35,12 +37,28 @@ protected override async Task ExecuteAsync(CommandContext context, SendComm new UnicastAddressTag(settings.DestinationEndpoint) ); - await rawEndpoint.Dispatch( - new TransportOperations(transportOperation), - new TransportTransaction() - ); + var sw = Stopwatch.StartNew(); + + await console.Status() + .Spinner(Spinner.Known.Dots) + .SpinnerStyle(Style.Parse("green")) + .StartAsync("Connecting to transport...", async ctx => + { + var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); + console.MarkupLine($"[green]:check_mark: Connected to transport[/] ([dim]{config.CurrentTransportConfig.Name}[/])"); + + ctx.Status("Sending message..."); + await rawEndpoint.Dispatch( + new TransportOperations(transportOperation), + new TransportTransaction() + ); + + await rawEndpoint.ShutDownAndCleanUp(); + }); + + sw.Stop(); - await rawEndpoint.ShutDownAndCleanUp(); + console.MarkupLine($"[green]:check_mark: Message sent [/]in [yellow]{sw.ElapsedMilliseconds}ms[/]"); return 0; } diff --git a/src/BuslyCLI.Console/Commands/NsbEvent/PublishCommand.cs b/src/BuslyCLI.Console/Commands/NsbEvent/PublishCommand.cs index ccbe18e..49632d4 100644 --- a/src/BuslyCLI.Console/Commands/NsbEvent/PublishCommand.cs +++ b/src/BuslyCLI.Console/Commands/NsbEvent/PublishCommand.cs @@ -1,20 +1,22 @@ -using System.Reflection; +using System.Diagnostics; +using System.Reflection; using System.Reflection.Emit; using System.Text; using BuslyCLI.Config; using BuslyCLI.Infrastructure.Factories; using NServiceBus.Routing; using NServiceBus.Transport; +using Spectre.Console; using Spectre.Console.Cli; namespace BuslyCLI.Commands.NsbEvent; -public class PublishCommand(IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand +public class PublishCommand(IAnsiConsole console, IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand { protected override async Task ExecuteAsync(CommandContext context, PublishCommandSettings settings, CancellationToken cancellationToken) { var config = await nServiceBusConfiguration.GetValidatedConfigurationAsync(settings.Config.Path); - var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); + // TODO: Validate body is valid json/xml var headers = new Dictionary { @@ -40,12 +42,28 @@ protected override async Task ExecuteAsync(CommandContext context, PublishC new MulticastAddressTag(type) ); - await rawEndpoint.Dispatch( - new TransportOperations(transportOperation), - new TransportTransaction() - ); + var sw = Stopwatch.StartNew(); + + await console.Status() + .Spinner(Spinner.Known.Dots) + // .SpinnerStyle(Style.Parse("green")) + .StartAsync("Connecting to transport...", async ctx => + { + var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); + console.MarkupLine($"[green]:check_mark: Connected to transport[/] ([dim]{config.CurrentTransportConfig.Name}[/])"); + + ctx.Status("Publishing message..."); + await rawEndpoint.Dispatch( + new TransportOperations(transportOperation), + new TransportTransaction() + ); + + await rawEndpoint.ShutDownAndCleanUp(); + }); + + sw.Stop(); - await rawEndpoint.ShutDownAndCleanUp(); + console.MarkupLine($"[green]:check_mark: Message published [/]in [yellow]{sw.ElapsedMilliseconds}ms[/]"); return 0; } diff --git a/src/BuslyCLI.Console/Commands/NsbTimeout/SendTimeout.cs b/src/BuslyCLI.Console/Commands/NsbTimeout/SendTimeout.cs index 24405ef..8b0f871 100644 --- a/src/BuslyCLI.Console/Commands/NsbTimeout/SendTimeout.cs +++ b/src/BuslyCLI.Console/Commands/NsbTimeout/SendTimeout.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Diagnostics; +using System.Text; using BuslyCLI.Config; using BuslyCLI.Config.Transports; using BuslyCLI.Infrastructure.Factories; @@ -31,7 +32,6 @@ protected override async Task ExecuteAsync(CommandContext context, SendTime return 1; } - var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); // TODO: Validate body is valid json/xml var headers = new Dictionary { @@ -66,12 +66,28 @@ protected override async Task ExecuteAsync(CommandContext context, SendTime dispatchProperties ); - await rawEndpoint.Dispatch( - new TransportOperations(transportOperation), - new TransportTransaction(), - cancellationToken); + var sw = Stopwatch.StartNew(); - await rawEndpoint.ShutDownAndCleanUp(); + await console.Status() + .Spinner(Spinner.Known.Dots) + .SpinnerStyle(Style.Parse("green")) + .StartAsync("Connecting to transport...", async ctx => + { + var rawEndpoint = await rawEndpointFactory.CreateRawSendOnlyEndpoint(Constants.DefaultOriginatingEndpoint, config.CurrentTransportConfig); + console.MarkupLine($"[green]:check_mark: Connected to transport[/] ([dim]{config.CurrentTransportConfig.Name}[/])"); + + ctx.Status("Sending timeout..."); + await rawEndpoint.Dispatch( + new TransportOperations(transportOperation), + new TransportTransaction(), + cancellationToken); + + await rawEndpoint.ShutDownAndCleanUp(); + }); + + sw.Stop(); + + console.MarkupLine($"[green]:check_mark: Timeout sent [/]in [yellow]{sw.ElapsedMilliseconds}ms[/]"); return 0; } diff --git a/website/docs/faq/_category_.json b/website/docs/faq/_category_.json new file mode 100644 index 0000000..1716868 --- /dev/null +++ b/website/docs/faq/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "FAQ", + "position": 5 +} diff --git a/website/docs/faq/faq.md b/website/docs/faq/faq.md new file mode 100644 index 0000000..e9da583 --- /dev/null +++ b/website/docs/faq/faq.md @@ -0,0 +1,48 @@ +--- +sidebar_position: 1 +title: FAQ +--- + +# Frequently Asked Questions + +## Why are my progress indicators and success messages not showing when I send a message? + +If you run a `send`, `publish`, or `timeout send` command and the spinner, `✔ Connected to transport`, or the final success line never appear, your terminal is likely not configured to output **UTF-8**. + +Busly CLI uses [Spectre.Console](https://spectreconsole.net) to render rich terminal output. Spectre.Console requires the console to be set to UTF-8 encoding in order to render Unicode characters (spinners, checkmarks, etc.) correctly. Without it, the output may be silently dropped or garbled. + +### Fix for PowerShell + +Add the following line to your PowerShell profile (or run it in your current session): + +```powershell +[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding +``` + +To make this permanent, add it to your `$PROFILE`: + +```powershell +notepad $PROFILE +``` + +Then paste the line above, save, and restart your terminal. + +### Fix for Windows Command Prompt + +Run the following before using Busly CLI: + +```cmd +chcp 65001 +``` + +### Emoji & Font Considerations + +Even with UTF-8 correctly configured, the appearance of indicators like `✔` may vary: + +- **Font Support** — Emoji rendering depends on your console's font. Not all fonts support color emoji; consider using a font like [Cascadia Code](https://github.com/microsoft/cascadia-code) or another Nerd Font. +- **Console Support** — Some consoles may display emoji as monochrome symbols instead of color icons. +- **Cross-Platform** — Emoji support varies across different operating systems and terminal applications. Linux and macOS terminals generally have better out-of-the-box support than Windows Console Host. + +### Additional Resources + +- [Spectre.Console Best Practices](https://spectreconsole.net/best-practices) — covers console encoding and other common setup tips. From b607c0a7c5cd24c5f17e6b95b6bfaf7958799413 Mon Sep 17 00:00:00 2001 From: Michael Fyffe <6224270+TraGicCode@users.noreply.github.com> Date: Thu, 7 May 2026 07:07:30 -0500 Subject: [PATCH 2/2] Make some changes to the docs for FAQ --- website/docs/faq/faq.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/website/docs/faq/faq.md b/website/docs/faq/faq.md index e9da583..8a39cc8 100644 --- a/website/docs/faq/faq.md +++ b/website/docs/faq/faq.md @@ -5,9 +5,9 @@ title: FAQ # Frequently Asked Questions -## Why are my progress indicators and success messages not showing when I send a message? +## Why are my progress indicators and success check marks not showing when I send a message? -If you run a `send`, `publish`, or `timeout send` command and the spinner, `✔ Connected to transport`, or the final success line never appear, your terminal is likely not configured to output **UTF-8**. +If you run a `send`, `publish`, or `timeout send` command and the spinner or ✔ checkmark never appear, your terminal is likely not configured to output **UTF-8**. Busly CLI uses [Spectre.Console](https://spectreconsole.net) to render rich terminal output. Spectre.Console requires the console to be set to UTF-8 encoding in order to render Unicode characters (spinners, checkmarks, etc.) correctly. Without it, the output may be silently dropped or garbled. @@ -43,6 +43,3 @@ Even with UTF-8 correctly configured, the appearance of indicators like `✔` ma - **Console Support** — Some consoles may display emoji as monochrome symbols instead of color icons. - **Cross-Platform** — Emoji support varies across different operating systems and terminal applications. Linux and macOS terminals generally have better out-of-the-box support than Windows Console Host. -### Additional Resources - -- [Spectre.Console Best Practices](https://spectreconsole.net/best-practices) — covers console encoding and other common setup tips.