Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions src/BuslyCLI.Console/Commands/NsbCommand/SendCommand.cs
Original file line number Diff line number Diff line change
@@ -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<SendCommandSettings>
public class SendCommand(IAnsiConsole console, IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand<SendCommandSettings>
{
protected override async Task<int> 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<string, string>
{
Expand All @@ -35,12 +37,28 @@ protected override async Task<int> 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;
}
Expand Down
34 changes: 26 additions & 8 deletions src/BuslyCLI.Console/Commands/NsbEvent/PublishCommand.cs
Original file line number Diff line number Diff line change
@@ -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<PublishCommandSettings>
public class PublishCommand(IAnsiConsole console, IRawEndpointFactory rawEndpointFactory, INServiceBusConfiguration nServiceBusConfiguration) : AsyncCommand<PublishCommandSettings>
{
protected override async Task<int> 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<string, string>
{
Expand All @@ -40,12 +42,28 @@ protected override async Task<int> 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;
}
Expand Down
30 changes: 23 additions & 7 deletions src/BuslyCLI.Console/Commands/NsbTimeout/SendTimeout.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System.Diagnostics;
using System.Text;
using BuslyCLI.Config;
using BuslyCLI.Config.Transports;
using BuslyCLI.Infrastructure.Factories;
Expand Down Expand Up @@ -31,7 +32,6 @@ protected override async Task<int> 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<string, string>
{
Expand Down Expand Up @@ -66,12 +66,28 @@ protected override async Task<int> 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;
}
Expand Down
4 changes: 4 additions & 0 deletions website/docs/faq/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "FAQ",
"position": 5
}
45 changes: 45 additions & 0 deletions website/docs/faq/faq.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
sidebar_position: 1
title: FAQ
---

# Frequently Asked Questions

## 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 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.

### 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.

Loading