diff --git a/pkgs/oizys/oizys-zig/src/Cli.zig b/pkgs/oizys/oizys-zig/src/Cli.zig index e61bac7..79094b7 100644 --- a/pkgs/oizys/oizys-zig/src/Cli.zig +++ b/pkgs/oizys/oizys-zig/src/Cli.zig @@ -3,9 +3,12 @@ const std = @import("std"); const yazap = @import("yazap"); const App = yazap.App; const Arg = yazap.Arg; - const Allocator = std.mem.Allocator; + +allocator: Allocator, app: App, +forward: ?[][]const u8 = null, +matches: *const yazap.ArgMatches = undefined, pub fn init(allocator: Allocator) !Cli { var app = App.init(allocator, "oizys", "nix begat oizys"); @@ -27,16 +30,41 @@ pub fn init(allocator: Allocator) !Cli { &cmd_switch, &cmd_boot, }) |subcmd| { + try subcmd.addArg(Arg.positional("forward", null, null)); try subcmd.addArg(Arg.singleValueOption("flake", 'f', "path to flake")); try subcmd.addArg(Arg.singleValueOption("host", null, "hostname (default: current host)")); try subcmd.addArg(Arg.booleanOption("no-pinix", null, "don't use pinix")); try oizys.addSubcommand(subcmd.*); } - // TODO: accept positinal args after -- to forward along? - return Cli{ .app = app }; + return Cli{ + .allocator = allocator, + .app = app, + }; +} + +pub fn parse(self: *Cli) !void { + const args = try std.process.argsAlloc(self.allocator); + defer std.process.argsFree(self.allocator, args); + var forward = std.ArrayList([]const u8).init(self.allocator); + + // TODO: simplify, this smells + const delim_idx = blk: { + for (args, 0..) |arg, i| + if (std.mem.eql(u8, "--", arg)) { + for (args[i + 1 ..]) |fwd| + try forward.append(try self.allocator.dupe(u8, fwd)); + break :blk i; + }; + break :blk args.len; + }; + + self.forward = try forward.toOwnedSlice(); + self.matches = try self.app.parseFrom(args[1..delim_idx]); } pub fn deinit(self: *Cli) void { self.app.deinit(); + for (self.forward) |arg| self.allocator.free(arg); + self.allocator.free(self.forward); } diff --git a/pkgs/oizys/oizys-zig/src/Oizys.zig b/pkgs/oizys/oizys-zig/src/Oizys.zig index b62f0ab..958e640 100644 --- a/pkgs/oizys/oizys-zig/src/Oizys.zig +++ b/pkgs/oizys/oizys-zig/src/Oizys.zig @@ -11,6 +11,7 @@ output: []const u8, cmd: OizysCmd, no_pinix: bool, debug: bool = false, +forward: ?[][]const u8, pub const OizysCmd = enum { dry, @@ -21,7 +22,7 @@ pub const OizysCmd = enum { build, }; -pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches) !Oizys { +pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches, forward: ?[][]const u8) !Oizys { const cmd = matches.subcommand.?.name; const flags = matches.subcommandMatches(cmd).?; const host = flags.getSingleValue("host") orelse @@ -41,6 +42,7 @@ pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches) !Oizys { .cmd = std.meta.stringToEnum(OizysCmd, cmd).?, .cache_name = flags.getSingleValue("cache") orelse "daylin", .no_pinix = flags.containsArg("no-pinix"), + .forward = forward, }; } @@ -91,6 +93,7 @@ pub fn runNixCmd(self: *Oizys, cmd: NixCmd, argv: []const []const u8) !void { NixCmd.NixosRebuild => try args.appendSlice(&.{ "sudo", self.nixos_rebuild() }), } try args.appendSlice(argv); + if (self.forward) |fwd| try args.appendSlice(fwd); var p = std.ChildProcess.init(args.items, self.allocator); _ = try p.spawnAndWait(); } diff --git a/pkgs/oizys/oizys-zig/src/main.zig b/pkgs/oizys/oizys-zig/src/main.zig index 269fd92..d04789a 100644 --- a/pkgs/oizys/oizys-zig/src/main.zig +++ b/pkgs/oizys/oizys-zig/src/main.zig @@ -9,13 +9,13 @@ pub fn main() !void { const allocator = arena.allocator(); var cli = try Cli.init(allocator); - const matches = try cli.app.parseProcess(); + try cli.parse(); - if (!matches.containsArgs()) { + if (!cli.matches.containsArgs()) { try cli.app.displayHelp(); return; } - var oizys = try Oizys.init(allocator, matches); + var oizys = try Oizys.init(allocator, cli.matches, cli.forward); try oizys.run(); }