Releases: xcaeser/zli
v3.7.0
zli v3.7.0
Important
Introducing Spinners! by @xcaeser in #16
Spinners are a new feature in zli
v3.7.0. Accessible through ctx.spinner, They are a powerful and customizable CLI spinner that can be used in any command's execFn
.
Here's an example of how it works:
fn run(ctx: CLICommandContext) !void {
const writer = ctx.command.stdout; // Convenience
// --- Example 1: Basic single-line spinner ---
try writer.print("\n--- Example 1: Single-Line Spinner ---\n", .{});
try ctx.spinner.start(.{}, "Starting a simple, single-line task...", .{});
std.time.sleep(2 * std.time.ns_per_s);
try ctx.spinner.succeed("Single-line task complete!", .{});
std.time.sleep(1 * std.time.ns_per_s);
// --- Example 2: Multi-step process ---
try writer.print("\n--- Example 2: Multi-Step Process ---\n", .{});
try ctx.spinner.start(.{}, "Step 1: Initializing network...", .{});
std.time.sleep(1500 * std.time.ms_per_s);
try ctx.spinner.nextStep("Step 2: Authenticating user...", .{});
std.time.sleep(1500 * std.time.ms_per_s);
try ctx.spinner.updateText("Step 2: Authentication is taking a moment...", .{});
std.time.sleep(1500 * std.time.ms_per_s);
try ctx.spinner.nextStep("Step 3: Fetching data...", .{});
std.time.sleep(2 * std.time.ns_per_s);
try ctx.spinner.fail("Failed to fetch data from server.", .{});
std.time.sleep(1 * std.time.ns_per_s);
// --- Example 3: Adding log lines during a process ---
try writer.print("\n--- Example 3: Process with Log Lines ---\n", .{});
try ctx.spinner.start(.{}, "Downloading and unpacking files...", .{});
std.time.sleep(1 * std.time.ns_per_s);
try ctx.spinner.addLine("Downloaded archive.zip (2.5 MB)", .{});
std.time.sleep(1 * std.time.ns_per_s);
try ctx.spinner.addLine("Unpacking to /tmp/my-app...", .{});
std.time.sleep(1500 * std.time.ms_per_s);
try ctx.spinner.addLine("Verified file integrity.", .{});
std.time.sleep(1 * std.time.ns_per_s);
try ctx.spinner.succeed("All files ready.", .{});
std.time.sleep(1 * std.time.ns_per_s);
// --- Example 4: Customizing style at runtime ---
try writer.print("\n--- Example 4: Customizing Style at Start ---\n", .{});
try ctx.spinner.start(.{
.frames = zli.SpinnerStyles.bouncing_bar,
.interval_ms = 120,
}, "Running with a different style...", .{});
std.time.sleep(3 * std.time.ns_per_s);
try ctx.spinner.info("Custom run finished for your information.", .{});
try writer.print("\n", .{});
}
full changelog: v3.6.3...v3.7.0
v3.6.3
v3.6.2
v3.6.1
v3.6.0
v3.5.3
v3.5.3
- added support for hidden flags
- help is now a defined flag for every command
Full changelog: v3.5.2...v3.5.3
v3.5.2
v3.5.1
Internal improvement
- Improved parsing to reduce number of loops = faster cli.
Full Changelog: v3.5.0...v3.5.1
v3.5.0
Important
NEW: Parsing of flags and positional args is interchangeable
Full Changelog: v3.4.0...v3.5.0
v3.4.0
π¦ v3.4.0 β Enhanced Positional Argument Support & UX Improvements
Release date: 2025-05-24
β¨ New Features
-
Positional Arguments:
- Added full support for required and variadic positional arguments.
- New API:
ctx.getArg("name")
for easy access to named positional inputs. - Enhanced help output now includes
Arguments
section with clear formatting. - Added automatic usage line generation with
printUsageLine()
.
-
Improved Help Output:
-
printHelp()
now includes:- Usage line with flags and args.
- Positional arguments list with required/variadic indicators.
- Improved call-to-action line (e.g.,
command --help
).
-
π Behavioral Changes
findLeaf()
now detects and handles unknown subcommands vs. expected positional args more gracefully.parsePositionalArgs()
enforces required arg count and variadic placement.
π§ͺ Tests Added
-
Coverage for:
- Positional argument enforcement.
getArg()
access behavior.- CLI structure integrity with nested commands and flags.
π§Ή Cleanups
- Removed unused legacy help/print code.
- Removed unused
CommandContext.flag()
fallback if no default exists (now unreachable by design).
[!IMPORTANT] This release includes breaking behavior for commands with positional arguments. If you use ctx.positional_args
directly, consider migrating to ctx.getArg("name")
.
Full Changelog: v3.3.1...v3.4.0