Automatic spinner disabling in non-interactive contexts
masterstdout is redirected (for example, in a CI/CD pipeline). This ensures that only the resulting text is printed rather than broken animation frames.repository·master·Indexed 20 days ago
https://github.com/mayuki/kurukuruA terminal spinner library for the .NET platform (.NET Framework, .NET Standard, and .NET 5+) that provides progress animations for long-running console tasks. It supports synchronous and asynchronous operations via Spinner.Start and Spinner.StartAsync, customizable patterns, and automatic fallback for non-Unicode environments and non-interactive contexts.
stdout is redirected (for example, in a CI/CD pipeline). This ensures that only the resulting text is printed rather than broken animation frames.Kurukuru is aware of non-Unicode codepages on Windows (e.g., CP437). If the environment is detected as non-Unicode, the library automatically renders using ASCII-character spinners by default to prevent broken characters.
To enable non-ASCII (Unicode) spinners in a Windows Command Prompt, you must:
You can install Kurukuru using either the Package Manager Console or the dotnet CLI.
# Package Manager Console
Install-Package Kurukuru
# dotnet command
dotnet add package KurukuruFor asynchronous operations, use the Spinner.StartAsync method. This accepts a Func<Task> or a Func<Spinner, Task> delegate. This is the recommended pattern for non-blocking I/O operations.
using Kurukuru;
// Simple async usage
await Spinner.StartAsync("Processing...", async () =>
{
await Task.Delay(1000 * 3);
});
// Async usage with text updates and failure
await Spinner.StartAsync("Stage 1...", async spinner =>
{
await Task.Delay(1000 * 3);
spinner.Text = "Stage 2...";
await Task.Delay(1000 * 3);
spinner.Fail("Something went wrong!");
});To run a synchronous spinner, add using Kurukuru; and call Spinner.Start. You can pass a text description and an Action<Spinner> delegate. Inside the delegate, you can modify the spinner.Text property or call spinner.Fail() to indicate failure. If an exception is thrown within the delegate, the spinner will show as failed.
using Kurukuru;
// Simple usage
Spinner.Start("Processing...", () =>
{
Thread.Sleep(1000 * 3);
});
// Usage with text updates and failure
Spinner.Start("Stage 1...", spinner =>
{
Thread.Sleep(1000 * 3);
spinner.Text = "Stage 2...";
Thread.Sleep(1000 * 3);
spinner.Fail("Something went wrong!");
});The Spinner.Start and Spinner.StartAsync methods create and start a new spinner that waits for the specified action to complete.
Parameters:
text: The text to display while the action is running.action: The long-running delegate (synchronous Action<Spinner> or asynchronous Func<Spinner, Task>).pattern: The spinner pattern to use (from the Patterns class). Defaults to Patterns.Dot. You can use patterns inspired by cli-spinners.fallbackPattern: The pattern used if the console's codepage is non-Unicode. Defaults to Patterns.Line.The Spinner instance provides the following properties:
Text: Gets or sets the text displayed alongside the spinner.Color: Gets or sets the color of the spinner icon (does not affect the text color).Once a spinner is running, you can use the following instance methods to control its lifecycle and visual output:
Stop(string text = null, string symbol = null, ConsoleColor? color = null): Stops the spinner and shows a result.Success(): Shows the result as a ✔ success (equivalent to Stop).Fail(string message): Shows the result as a ✖ failure (equivalent to Stop).Warning(): Shows the result as a ⚠ warning (equivalent to Stop).Info(): Shows the result as a ℹ information (equivalent to Stop).