Another CLI Library

Project link: https://codeberg.org/jeffective/cli

Hello everyone, I’ve repackaged my std.cli attempt (command line argument parser) as a module. The ethos behind the design is explained in detail in the PR, but the short version is that it is an attempt at being the opposite of “type-driven” while retaining the same direct access to parsed fields. This means the parse function can be understood first from the types of its arguments, instead of its docs.

So the following cli definition:

pub const command: cli.Command = .{
    .name = .cowsay,
    .positional_args = &.{
        .init(.message, [:0]const u8, .{ .help = "Message said by the cow." }),
    },
    .named_args = &.{
        .init(.red, bool, .{ .help = "Change text color to red.", .default_value = false }),
    },
    .help = "Make a cow speak.\n",
};

can use the parse result like this:

const parsed = try cli.parse(
    command,
    try init.minimal.args.toSlice(init.arena.allocator()),
    .{
        .exit_usage_error = true,
        .render_usage_errors = true,
        .exit_help = true,
        .render_help = .{ .generated = io },
    },
);

...

if (parsed.kind.args.red) {
    try out.writeAll("\x1b[31m");
}
...

try out.print("{s}", .{parsed.kind.args.message});

Unfortunately there is a lot of comptime in there, so ZLS won’t be able to provide autocomplete until the compiler server comes, but I really like working directly with the types like this, already parsed for me (like std.json).

Supported Zig versions

  • 0.17.0
  • 0.16.0
19 Likes

Codeberg is down at the moment (sigh) so pardon me if this is answered in the linked PR, but does “attempt” mean that the effort ultimately was rejected, that it’s in discussion, etc?

iirc, I think the accepted proposal now includes a spec for a more “type-driven” design ?

Yes, core team ultimately decided to stay with type-driven. There were many designs proposed with real implementations to back them up, you should take a look! Lots of interesting ways people approached it.

1 Like

yours was my favorite, I really liked the API so I’m glad you saved it as a library :slight_smile:

1 Like

Nice work. I followed the cli discussion with interest, and I wonder if anyone is working on the accepted proposal. I will try out yours in the weekend.

1 Like

I was actually looking for a CLI library earlier and thought back to your PR which (to me) was superior to the API provided by the existing libraries I found, so started using this :tada: