e917196e218f

apply: auto-detect flake.nix and pass --flake for non-default config paths — exec.configHasFlake checks machine.config_path/flake.nix locally; useFlakeFlag gates on presence AND path != /etc/nixos (which nixos-rebuild auto-detects); switch/dry-activate/build routed through nixosRebuildRun; switch substep shows the --flake path; build+tests green

time
2026-06-10 01:21 UTC · 4 months ago
machine
koh2
agent
claude-opus-4-8
session
flake + home manager support
parent
73ca9ec06eb5
1 file src/exec.zig+36 −5
src/exec.zig+36 −5
@@ -171,18 +171,49 @@171171 172172 // --- NixOS rebuild ---173173 174+// True if the machine's config dir holds a flake.nix. Only meaningful for a local175+// machine — the file lives on the local filesystem. Remote flake detection would176+// need an ssh round-trip; a remote flake at the default /etc/nixos needs no flag177+// anyway, so we don't bother.178+pub fn configHasFlake(gpa: std.mem.Allocator, io: std.Io, machine: *const types.Machine) bool {179+    if (!machine.local) return false;180+    const flake_path = std.fs.path.join(gpa, &.{ machine.config_path, "flake.nix" }) catch return false;181+    defer gpa.free(flake_path);182+    const f = std.Io.Dir.openFile(.cwd(), io, flake_path, .{}) catch return false;183+    f.close(io);184+    return true;185+}186+187+// nixos-rebuild auto-detects /etc/nixos/flake.nix, so the --flake flag is only188+// needed when the flake lives elsewhere. A flake at a non-default path must be189+// passed explicitly or nixos-rebuild falls back to channels.190+fn useFlakeFlag(gpa: std.mem.Allocator, io: std.Io, machine: *const types.Machine) bool {191+    return configHasFlake(gpa, io, machine) and !std.mem.eql(u8, machine.config_path, "/etc/nixos");192+}193+194+fn nixosRebuildRun(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator, verb: []const u8, flake: bool) !u8 {195+    if (flake) {196+        return stream(io, machine, gpa, &.{ "sudo", "nixos-rebuild", verb, "--flake", machine.config_path });197+    }198+    return stream(io, machine, gpa, &.{ "sudo", "nixos-rebuild", verb });199+}200+174201 pub fn nixosRebuildSwitch(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {175-    const cmd = &.{ "sudo", "nixos-rebuild", "switch" };176-    output.printSubstep("nixos-rebuild switch", .{});177-    return stream(io, machine, gpa, cmd);202+    const flake = useFlakeFlag(gpa, io, machine);203+    if (flake) {204+        output.printSubstep("nixos-rebuild switch --flake {s}", .{machine.config_path});205+    } else {206+        output.printSubstep("nixos-rebuild switch", .{});207+    }208+    return nixosRebuildRun(io, machine, gpa, "switch", flake);178209 }179210 180211 pub fn nixosRebuildDryActivate(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {181-    return stream(io, machine, gpa, &.{ "sudo", "nixos-rebuild", "dry-activate" });212+    return nixosRebuildRun(io, machine, gpa, "dry-activate", useFlakeFlag(gpa, io, machine));182213 }183214 184215 pub fn nixosRebuildBuild(io: std.Io, machine: *const types.Machine, gpa: std.mem.Allocator) !u8 {185-    return stream(io, machine, gpa, &.{ "sudo", "nixos-rebuild", "build" });216+    return nixosRebuildRun(io, machine, gpa, "build", useFlakeFlag(gpa, io, machine));186217 }187218 188219 // --- Generations ---

view file