2bd71fb27d78
apply/upgrade: thread ctx.passthrough into nixos-rebuild switch argv
- time
- 2026-07-02 00:54 UTC · 3 months ago
- machine
- koh2
- agent
- claude-sonnet-5
- session
- nina passthrough flag audit
- parent
- d00f8194f384
↓ nina-2bd71fb2.tar.gzatlas at this save
files changed3 files
src/commands.zig+4 −4src/exec.zig+24 −18src/main.zig+34 −0src/commands.zig+4 −4
@@ -68,7 +68,7 @@6868 pub fn apply(ctx: Ctx) !void {6969 if (ctx.dry) {7070 output.applyDry(ctx.machine.name);71- const code = try exec.nixosRebuildDryActivate(ctx.io, &ctx.machine, ctx.gpa);71+ const code = try exec.nixosRebuildDryActivate(ctx.io, &ctx.machine, ctx.gpa, ctx.passthrough);7272 if (code != 0) return error.BuildFailed;7373 output.applyDryDone();7474 return;@@ -87,7 +87,7 @@8787 const start = std.Io.Clock.awake.now(ctx.io);8888 8989 var panel = output.BuildPanel{};90- const code = exec.nixosRebuildSwitchWithPanel(ctx.io, &ctx.machine, ctx.gpa, &panel) catch |e| {90+ const code = exec.nixosRebuildSwitchWithPanel(ctx.io, &ctx.machine, ctx.gpa, &panel, ctx.passthrough) catch |e| {9191 output.buildPanelClear();9292 exec.markApplyFailed(ctx.io, ctx.environ);9393 return e;@@ -117,7 +117,7 @@117117 118118 pub fn check(ctx: Ctx) !void {119119 output.checkStart(ctx.machine.name);120- const code = try exec.nixosRebuildBuild(ctx.io, &ctx.machine, ctx.gpa);120+ const code = try exec.nixosRebuildBuild(ctx.io, &ctx.machine, ctx.gpa, ctx.passthrough);121121 if (code != 0) return error.BuildFailed;122122 output.checkOk();123123 }@@ -809,7 +809,7 @@809809 output.buildPanelInit();810810 const start = std.Io.Clock.awake.now(ctx.io);811811 var panel = output.BuildPanel{};812- const code = exec.nixosRebuildSwitchWithPanel(ctx.io, &ctx.machine, ctx.gpa, &panel) catch |e| {812+ const code = exec.nixosRebuildSwitchWithPanel(ctx.io, &ctx.machine, ctx.gpa, &panel, ctx.passthrough) catch |e| {813813 output.buildPanelClear();814814 return e;815815 };src/exec.zig+24 −18
@@ -351,27 +351,29 @@351351 // output is suppressed; on failure, reportError() translates stderr via352352 // errors.translateError(). The substep line above the call tells the user what353353 // is running; silence during the build is intentional per the error-wrapping brief.354-fn nixosRebuildRun(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, verb: []const u8, flake: bool) !u8 {355- const argv: []const []const u8 = if (flake)356- &.{ "sudo", "nixos-rebuild", verb, "--flake", machine.config_path }357- else358- &.{ "sudo", "nixos-rebuild", verb };354+fn nixosRebuildRun(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, verb: []const u8, flake: bool, extra_flags: []const []const u8) !u8 {355+ var argv: std.ArrayList([]const u8) = .empty;356+ defer argv.deinit(gpa);357+ try argv.appendSlice(gpa, &.{ "sudo", "nixos-rebuild", verb });358+ if (flake) try argv.appendSlice(gpa, &.{ "--flake", machine.config_path });359+ try argv.appendSlice(gpa, extra_flags);360+359361 output.flush();360- const r = try capture(gpa, io, machine, argv);362+ const r = try capture(gpa, io, machine, argv.items);361363 defer gpa.free(r.stdout);362364 defer gpa.free(r.stderr);363365 errors.setBuildStderr(r.stderr);364366 return r.exit_code;365367 }366368 367-pub fn nixosRebuildSwitch(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {369+pub fn nixosRebuildSwitch(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, extra_flags: []const []const u8) !u8 {368370 const flake = useFlakeFlag(gpa, io, machine);369371 if (flake) {370372 output.printSubstep("nixos-rebuild switch --flake {s}", .{machine.config_path});371373 } else {372374 output.printSubstep("nixos-rebuild switch", .{});373375 }374- return nixosRebuildRun(io, machine, gpa, "switch", flake);376+ return nixosRebuildRun(io, machine, gpa, "switch", flake, extra_flags);375377 }376378 377379 // Live-streaming variant used by `apply` when stdout is a TTY. Each stderr line@@ -383,6 +385,7 @@383385 machine: *const types.Machine,384386 gpa: std.mem.Allocator,385387 panel: *output.BuildPanel,388+ extra_flags: []const []const u8,386389 ) !u8 {387390 const flake = useFlakeFlag(gpa, io, machine);388391 if (flake) {@@ -390,8 +393,8 @@390393 } else {391394 output.printSubstep("nixos-rebuild switch", .{});392395 }393- if (!output.colorEnabled()) return nixosRebuildRun(io, machine, gpa, "switch", flake);394- return nixosRebuildRunStreamed(io, machine, gpa, "switch", flake, panel);396+ if (!output.colorEnabled()) return nixosRebuildRun(io, machine, gpa, "switch", flake, extra_flags);397+ return nixosRebuildRunStreamed(io, machine, gpa, "switch", flake, panel, extra_flags);395398 }396399 397400 fn nixosRebuildRunStreamed(@@ -401,11 +404,14 @@401404 verb: []const u8,402405 flake: bool,403406 panel: *output.BuildPanel,407+ extra_flags: []const []const u8,404408 ) !u8 {405- const argv: []const []const u8 = if (flake)406- &.{ "sudo", "nixos-rebuild", verb, "--flake", machine.config_path }407- else408- &.{ "sudo", "nixos-rebuild", verb };409+ var argv_list: std.ArrayList([]const u8) = .empty;410+ defer argv_list.deinit(gpa);411+ try argv_list.appendSlice(gpa, &.{ "sudo", "nixos-rebuild", verb });412+ if (flake) try argv_list.appendSlice(gpa, &.{ "--flake", machine.config_path });413+ try argv_list.appendSlice(gpa, extra_flags);414+ const argv: []const []const u8 = argv_list.items;409415 410416 output.flush();411417 const built_argv = try buildArgv(gpa, machine, argv);@@ -449,12 +455,12 @@449455 };450456 }451457 452-pub fn nixosRebuildDryActivate(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {453- return nixosRebuildRun(io, machine, gpa, "dry-activate", useFlakeFlag(gpa, io, machine));458+pub fn nixosRebuildDryActivate(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, extra_flags: []const []const u8) !u8 {459+ return nixosRebuildRun(io, machine, gpa, "dry-activate", useFlakeFlag(gpa, io, machine), extra_flags);454460 }455461 456-pub fn nixosRebuildBuild(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {457- return nixosRebuildRun(io, machine, gpa, "build", useFlakeFlag(gpa, io, machine));462+pub fn nixosRebuildBuild(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, extra_flags: []const []const u8) !u8 {463+ return nixosRebuildRun(io, machine, gpa, "build", useFlakeFlag(gpa, io, machine), extra_flags);458464 }459465 460466 // --- Generations ---src/main.zig+34 −0
@@ -361,6 +361,40 @@361361 try std.testing.expectEqualStrings("--refresh", args.passthrough[0]);362362 }363363 364+test "parse args forwards apply --show-trace" {365+ const gpa = std.testing.allocator;366+ const argv = [_][:0]const u8{ "nina", "apply", "--show-trace" };367+ const args = try parseArgs(gpa, &argv);368+ defer gpa.free(args.rest);369+ defer gpa.free(args.passthrough);370+ try std.testing.expectEqualStrings("apply", args.command);371+ try std.testing.expectEqual(@as(usize, 1), args.passthrough.len);372+ try std.testing.expectEqualStrings("--show-trace", args.passthrough[0]);373+}374+375+test "parse args forwards check --show-trace" {376+ const gpa = std.testing.allocator;377+ const argv = [_][:0]const u8{ "nina", "check", "--show-trace" };378+ const args = try parseArgs(gpa, &argv);379+ defer gpa.free(args.rest);380+ defer gpa.free(args.passthrough);381+ try std.testing.expectEqualStrings("check", args.command);382+ try std.testing.expectEqual(@as(usize, 1), args.passthrough.len);383+ try std.testing.expectEqualStrings("--show-trace", args.passthrough[0]);384+}385+386+test "parse args forwards flake check --all-systems" {387+ const gpa = std.testing.allocator;388+ const argv = [_][:0]const u8{ "nina", "flake", "check", "--all-systems" };389+ const args = try parseArgs(gpa, &argv);390+ defer gpa.free(args.rest);391+ defer gpa.free(args.passthrough);392+ try std.testing.expectEqualStrings("flake", args.command);393+ try std.testing.expectEqualStrings("check", args.sub);394+ try std.testing.expectEqual(@as(usize, 1), args.passthrough.len);395+ try std.testing.expectEqualStrings("--all-systems", args.passthrough[0]);396+}397+364398 test "parse subcommand" {365399 const gpa = std.testing.allocator;366400 const argv = [_][:0]const u8{ "nina", "service", "list" };