diff options
Diffstat (limited to '')
| -rw-r--r-- | src/main.zig | 151 |
1 files changed, 92 insertions, 59 deletions
diff --git a/src/main.zig b/src/main.zig index 53048df..b99f28c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -24,6 +24,77 @@ pub fn main(init: std.process.Init) !void { var FORCE: bool = false; const Cli = struct { + const FlagSet = std.BufSet; + + const Flag = struct { + name: []const u8, + help: []const u8 = "", + }; + + const Command = struct { + name: []const u8, + help: []const u8 = "", + flags: []const Flag = &.{}, + subcommands: []const Command = &.{}, + handler: *const fn (io: Io, gpa: Allocator, flags: FlagSet, args: [][]const u8) anyerror!void, + + fn run(self: Command, io: Io, gpa: Allocator, opts: *std.process.Args.Iterator) !void { + var flags: std.BufSet = .init(gpa); + defer flags.deinit(); + var args: std.ArrayList([]const u8) = .empty; + defer args.deinit(gpa); + + optLoop: while (opts.next()) |o| { + if (std.mem.eql(u8, o, "help")) return Cli.usage(); + if (std.mem.eql(u8, o, "--help")) return Cli.usage(); + if (std.mem.eql(u8, o, "-h")) return Cli.usage(); + + for (self.flags) |f| + if (std.mem.eql(u8, o, f.name)) { + try flags.insert(f.name); + continue :optLoop; + }; + for (self.subcommands) |c| + if (std.mem.eql(u8, o, c.name)) { + try c.run(io, gpa, opts); + return; // terminate with subcommand + }; + try args.append(gpa, o); + } + + try self.handler(io, gpa, flags, args.items); + return; + } + }; + + const root = Command{ + .name = "rbc", + .subcommands = &.{ + .{ + .name = "build", + .flags = &.{ .{ .name = "-f" }, .{ .name = "--force" } }, + .handler = &Cli.build, + }, + .{ + .name = "mdn", + .handler = &Cli.markdown, + }, + .{ + .name = "gen", + .flags = &.{ + .{ .name = "-f" }, + .{ .name = "--force" }, + }, + .handler = &Cli.gen, + }, + }, + .handler = struct { + fn inner(_: Io, _: Allocator, _: std.BufSet, _: [][]const u8) anyerror!void { + return Cli.usage(); + } + }.inner, + }; + fn usage() void { std.debug.print( \\usage: rbc [command] [options] @@ -43,42 +114,21 @@ const Cli = struct { } fn run(init: std.process.Init) !void { - const io = init.io; - const gpa = init.gpa; - if (init.environ_map.get("RBC_FORCE")) |_| FORCE = true; // parse options var opts = init.minimal.args.iterate(); - _ = opts.skip(); - while (opts.next()) |o| { - if (std.mem.eql(u8, o, "help")) return Cli.usage(); - if (std.mem.eql(u8, o, "--help")) return Cli.usage(); - if (std.mem.eql(u8, o, "-h")) return Cli.usage(); - if (std.mem.eql(u8, o, "build")) return Cli.build(io, gpa, &opts); - if (std.mem.eql(u8, o, "gen")) return Cli.gen(io, gpa, &opts); - if (std.mem.eql(u8, o, "mdn")) return Cli.markdown(io, gpa, &opts); - } - return Cli.usage(); + _ = opts.skip(); // skip arg0 + return Cli.root.run(init.io, init.gpa, &opts); } - fn build(io: Io, gpa: Allocator, opts: *std.process.Args.Iterator) !void { - var args: std.ArrayList([]const u8) = .empty; - defer args.deinit(gpa); - - while (opts.next()) |o| { - if (std.mem.eql(u8, o, "help")) return Cli.usage(); - if (std.mem.eql(u8, o, "--help")) return Cli.usage(); - if (std.mem.eql(u8, o, "-h")) return Cli.usage(); - if (std.mem.eql(u8, o, "--force")) FORCE = true and continue; - if (std.mem.eql(u8, o, "-f")) FORCE = true and continue; - try args.append(gpa, o); - } - - if (args.items.len < 2) return Cli.usage(); + fn build(io: Io, gpa: Allocator, flags: FlagSet, args: [][]const u8) !void { + if (flags.contains("--force")) FORCE = true; + if (flags.contains("-f")) FORCE = true; + if (args.len < 2) return Cli.usage(); - const source_path = args.items[0]; - const target_path = args.items[1]; + const source_path = args[0]; + const target_path = args[1]; log.info("build : target={s} source={s}", .{ target_path, source_path }); @@ -99,23 +149,18 @@ const Cli = struct { try b.build(io, gpa); } - fn gen(io: Io, gpa: Allocator, opts: *std.process.Args.Iterator) !void { - var args: std.ArrayList([]const u8) = .empty; - defer args.deinit(gpa); + fn gen(io: Io, gpa: Allocator, flags: FlagSet, args: [][]const u8) !void { + if (flags.contains("--force")) FORCE = true; + if (flags.contains("-f")) FORCE = true; - while (opts.next()) |o| { - if (std.mem.eql(u8, o, "help")) return Cli.usage(); - if (std.mem.eql(u8, o, "--help")) return Cli.usage(); - if (std.mem.eql(u8, o, "-h")) return Cli.usage(); - if (std.mem.eql(u8, o, "--force")) FORCE = true and continue; - if (std.mem.eql(u8, o, "-f")) FORCE = true and continue; - try args.append(gpa, o); - } + var LIST = false; + if (flags.contains("-l")) LIST = true; + if (flags.contains("--list")) LIST = true; - if (args.items.len < 2) return Cli.usage(); + if (args.len < 2) return Cli.usage(); - const root_path = args.items[0]; - const target_path = args.items[1]; + const root_path = args[0]; + const target_path = args[1]; log.info("gen : target={s} root={s}", .{ target_path, root_path }); @@ -183,23 +228,11 @@ const Cli = struct { } } - fn markdown(io: Io, gpa: Allocator, opts: *std.process.Args.Iterator) !void { - var args: std.ArrayList([]const u8) = .empty; - defer args.deinit(gpa); - - while (opts.next()) |o| { - if (std.mem.eql(u8, o, "help")) return Cli.usage(); - if (std.mem.eql(u8, o, "--help")) return Cli.usage(); - if (std.mem.eql(u8, o, "-h")) return Cli.usage(); - // if (std.mem.eql(u8, o, "--force")) FORCE = true and continue; - // if (std.mem.eql(u8, o, "-f")) FORCE = true and continue; - try args.append(gpa, o); - } - - if (args.items.len < 2) return Cli.usage(); + fn markdown(io: Io, gpa: Allocator, _: FlagSet, args: [][]const u8) !void { + if (args.len < 2) return Cli.usage(); - const source_path = args.items[0]; - const target_path = args.items[1]; + const source_path = args[0]; + const target_path = args[1]; log.info("mdn : target={s} source={s}", .{ target_path, source_path }); |