prajwalch / yazap

🔧 The ultimate Zig library for seamless command line argument parsing.
https://prajwalch.github.io/yazap
MIT License
152 stars 13 forks source link

Support passing positional arguments after options #8

Closed asynts closed 1 year ago

asynts commented 1 year ago

It seems that the parser is confused if it encounters a boolean flag before the positional argument:

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

var gpa = std.heap.GeneralPurposeAllocator(.{
    .safety = true,
}){};

pub fn main() !void {
    const allocator = gpa.allocator();

    var app = yazap.App.init(allocator, "example", null);
    defer app.deinit();

    var root_command = app.rootCommand();

    try root_command.addArg(yazap.flag.boolean("example", null, null));
    try root_command.takesSingleValue("file");

    var args = try app.parseProcess();

    if (args.valueOf("file")) |file| {
        std.debug.print("got file: '{s}'\n", .{ file });
    }
}
$ ./example foo --example
got file: 'foo'
~/tmp/yazap-repro/zig-out/bin (me)
$ ./example --example foo
Unknown Command 'foo'
error: UnknownCommand
/home/me/tmp/yazap-repro/libs/yazap/src/Parser.zig:444:9: 0x25b893 in parseSubCommand (example)
        return Error.UnknownCommand;
        ^
/home/me/tmp/yazap-repro/libs/yazap/src/Parser.zig:109:17: 0x244209 in parse (example)
                try self.parseSubCommand(token.value),
                ^
/home/me/tmp/yazap-repro/libs/yazap/src/App.zig:60:9: 0x21d765 in parseFrom (example)
        return e;
        ^
/home/me/tmp/yazap-repro/libs/yazap/src/App.zig:50:5: 0x2181a0 in parseProcess (example)
    return self.parseFrom(self.process_args.?[1..]);
    ^
/home/me/tmp/yazap-repro/src/main.zig:19:16: 0x217b2e in main (example)
    var args = try app.parseProcess();
prajwalch commented 1 year ago

This is because currently the parser expects the positional arguments to be passed before any flags (i.e cmd POS_ARGS OPTIONS ) and any argument that is passed after the options will be parsed as a either options value or subcommand therefore to fix this issue the implementation of parser need to be changed to support passing positional arguments in both way (before options and after options).

prajwalch commented 1 year ago

@asynts This is now patched and closing this issue as completed. Thank you for opening this issue :)

asynts commented 1 year ago

I've tried it and it works now. Thank you.