8000 GitHub - xcaeser/zli: πŸ“Ÿ Zig command-line interfaces made easy. A blazing fast CLI framework. Build ergonomic, high-performance command-line tools with zig.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ zli Public

πŸ“Ÿ Zig command-line interfaces made easy. A blazing fast CLI framework. Build ergonomic, high-performance command-line tools with zig.

License

Notifications You must be signed in to change notification settings

xcaeser/zli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“Ÿ zli

A blazing-fast, zero-cost CLI framework for Zig. The last one you will ever use.

Build modular, ergonomic, and high-performance CLIs with ease. All batteries included.

Tests Zig Version License: MIT Built by xcaeser Version

Tip

🧱 Each command is modular and self-contained.

πŸ“š Documentation

See docs.md for full usage, examples, and internals.

πŸš€ Highlights

  • Modular commands & subcommands
  • Fast flag parsing (--flag, --flag=value, shorthand -abc)
  • Type-safe support for bool, int, string
  • Named positional arguments with required, optional, variadic
  • Auto help/version/deprecation handling
  • Pretty help output with aligned flags & args
  • Spinners (new in v3.7.0)
  • Usage hints, context-aware

πŸ“¦ Installation

zig fetch --save=zli https://github.com/xcaeser/zli/archive/v3.7.0.tar.gz

Add to your build.zig:

const zli_dep = b.dependency("zli", .{ .target = target });
exe.root_module.addImport("zli", zli_dep.module("zli"));

πŸ—‚ Suggested Structure

your-app/
β”œβ”€β”€ build.zig
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.zig
β”‚   └── cli/
β”‚       β”œβ”€β”€ root.zig
β”‚       β”œβ”€β”€ run.zig
β”‚       └── version.zig
  • Each command is in its own file
  • You explicitly register subcommands
  • root.zig is the entry point

πŸ§ͺ Example

// src/main.zig
const std = @import("std");
const cli = @import("cli/root.zig");

pub fn main() !void {
    const allocator = std.heap.smp_allocator;
    var root = try cli.build(allocator);
    defer root.deinit();

    try root.execute(.{}); // Or pass data with: try root.execute(.{ .data = &my_data });
}
// src/cli/root.zig
const std = @import("std");
const zli = @import("zli");

const run = @import("run.zig");
const version = @import("version.zig");

pub fn build(allocator: std.mem.Allocator) !*zli.Command {
    const root = try zli.Command.init(allocator, .{
        .name = "blitz",
        .description = "Your dev toolkit CLI",
    }, showHelp);

    try root.addCommands(&.{
        try run.register(allocator),
        try version.register(allocator),
    });

    return root;
}

fn showHelp(ctx: zli.CommandContext) !void {
    try ctx.command.printHelp();
}
// src/cli/run.zig
const std = @import("std");
const zli = @import("zli");

const now_flag = zli.Flag{
    .name = "now",
    .shortcut = "n",
    .description = "Run immediately",
    .type = .Bool,
    .default_value = .{ .Bool = false },
};

pub fn register(allocator: std.mem.Allocator) !*zli.Command {
    const cmd = try zli.Command.init(allocator, .{
        .name = "run",
        .description = "Run your workflow",
    }, run);

    try cmd.addFlag(now_flag);
    try cmd.addPositionalArg(.{
        .name = "script",
        .description = "Script to execute",
        .required = true,
    });
    try cmd.addPositionalArg(.{
        .name = "env",
        .description = "Environment name",
        .required = false,
    });

    return cmd;
}

fn run(ctx: zli.CommandContext) !void {
    const now = ctx.flag("now", bool); // type-safe flag access

    const script = ctx.getArg("script") orelse {
        try ctx.command.stderr.print("Missing script arg\n", .{});
        return;
    };
    const env = ctx.getArg("env") orelse "default";

    std.debug.print("Running {s} in {s} (now = {})\n", .{ script, env, now });

    // You can also get other commands by name:
    // if (ctx.root.findCommand("create")) |create_cmd| {
    //    try create_cmd.printUsageLine();
    // }

    // if you passed data to your root command, you can access it here:
    // const object = ctx.getContextData(type_of_your_data); // can be struct, []const u8, etc., object is a pointer.

};
// src/cli/version.zig
const std = @import("std");
const zli = @import("zli");

pub fn register(allocator: std.mem.Allocator) !*zli.Command {
    return zli.Command.init(allocator, .{
        .name = "version",
        .shortcut = "v",
        .description = "Show CLI version",
    }, show);
}

fn show(ctx: zli.CommandContext) !void {
    std.debug.print("{?}\n", .{ctx.root.options.version});
}

Spinners example

const std = @import("std");
const zli = @import("zli");

pub fn run(ctx: zli.CommandContext) !void {
    // Step 1: Start the first task.
    try ctx.spinner.start(.{}, "Connecting to vault...", .{});
    doSomething();
    try ctx.spinner.updateText("Step 2: Authentication is taking a moment...", .{});
    doSomething();

    // Step 2: Mark Step 1 as complete and start the next task.
    const key = ctx.getArg("key") orelse "b";
    try ctx.spinner.nextStep("Retrieving key '{s}'...", .{key});
    doSomething();

    // Step 3: Mark Step 2 as complete and start the final task.
    try ctx.spinner.nextStep("Decrypting value...", .{});
    const value = try zv.getFromVault(key);
    const fl = ctx.flag("now", bool);
    doSomething();

    // Step 4: Mark the final task as successful and stop.
    try ctx.spinner.succeed("Success! Found value: {s} (flag: {any})", .{ value, fl });
}


## βœ… Features Checklist

- [x] Commands & subcommands
- [x] Command aliases
- [x] Flags & shorthands
- [x] Type-safe flag values
- [x] Positional args (required, optional, variadic)
- [x] Named access: `ctx.getArg("name")`
- [x] Context data
- [x] Help/version auto handling
- [x] Deprecation notices
- [x] Pretty-aligned help for flags & args
- [x] Clean usage output like Cobra
- [x] Spinners and loading state (very powerful)
- [ ] Persistent flags

## πŸ“ License

MIT. See [LICENSE](LICENSE). Contributions welcome.

About

πŸ“Ÿ Zig command-line interfaces made easy. A blazing fast CLI framework. Build ergonomic, high-performance command-line tools with zig.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published
0