41b75b265eb0

implement registry auto-pin: pin nixpkgs once via ~/.nina-registry-pinned flag, announced before search/install/setup

time
2026-06-04 23:00 UTC · 4 months ago
machine
koh2
agent
claude-opus-4-8
session
registry auto-pin
parent
670b260dac73
3 files src/api.zig+32 −0src/commands.zig+6 −0src/output.zig+7 −0
src/api.zig+32 −0
@@ -3,6 +3,38 @@33 const std = @import("std");44 const types = @import("types.zig");55 const errors = @import("errors.zig");6+const output = @import("output.zig");7+8+// Pin the nixpkgs registry once so `nix search nixpkgs` resolves locally instead9+// of refetching github on every query. Gated by a ~/.nina-registry-pinned flag:10+// absent -> pin + announce + create the flag; present -> no-op, silent. Failure11+// to pin is non-fatal — search still runs (just slower), and the flag is left12+// absent so a later run retries.13+pub fn ensureRegistryPinned(gpa: std.mem.Allocator, io: std.Io, environ: *const std.process.Environ.Map) void {14+    const home = environ.get("HOME") orelse return;15+    const flag_path = std.fmt.allocPrint(gpa, "{s}/.nina-registry-pinned", .{home}) catch return;16+    defer gpa.free(flag_path);17+18+    if (std.Io.Dir.openFile(.cwd(), io, flag_path, .{})) |f| {19+        f.close(io);20+        return; // already pinned21+    } else |_| {}22+23+    output.pinningRegistry();24+25+    const r = std.process.run(gpa, io, .{26+        .argv = &.{ "nix", "registry", "pin", "nixpkgs" },27+    }) catch return;28+    defer gpa.free(r.stdout);29+    defer gpa.free(r.stderr);30+    switch (r.term) {31+        .exited => |code| if (code != 0) return,32+        else => return,33+    }34+35+    const file = std.Io.Dir.createFile(.cwd(), io, flag_path, .{}) catch return;36+    file.close(io);37+}638 739 pub fn searchPackages(gpa: std.mem.Allocator, io: std.Io, query: []const u8) ![]types.NixPackage {840     const result = std.process.run(gpa, io, .{

view file

src/commands.zig+6 −0
@@ -443,6 +443,7 @@443443 444444 pub fn searchCmd(ctx: Ctx) !void {445445     const query = if (ctx.args.len > 0) ctx.args[0] else "";446+    api.ensureRegistryPinned(ctx.gpa, ctx.io, ctx.environ);446447     const result = try search_tui.run(ctx.gpa, ctx.io, query, .packages);447448     if (result) |r| {448449         installFromResult(ctx, r) catch |e| return e;@@ -451,12 +452,15 @@451452 452453 pub fn optionCmd(ctx: Ctx) !void {453454     const query = if (ctx.args.len > 0) ctx.args[0] else "";455+    api.ensureRegistryPinned(ctx.gpa, ctx.io, ctx.environ);454456     _ = try search_tui.run(ctx.gpa, ctx.io, query, .options);455457 }456458 457459 pub fn install(ctx: Ctx) !void {458460     const pkg_name = if (ctx.args.len > 0) ctx.args[0] else return error.PackageNotFound;459461 462+    api.ensureRegistryPinned(ctx.gpa, ctx.io, ctx.environ);463+460464     // Search for the package to get the attr461465     const pkgs = api.searchPackages(ctx.gpa, ctx.io, pkg_name) catch {462466         errors.error_info.setMessage("'{s}' not found in nixpkgs", .{pkg_name});@@ -848,6 +852,7 @@848852 849853     if (status.allEnabled()) {850854         output.setupAllSet();855+        api.ensureRegistryPinned(gpa, io, environ);851856         return;852857     }853858 @@ -856,6 +861,7 @@856861     defer gpa.free(path);857862 858863     output.setupDone(path, exec.isNixOS(io));864+    api.ensureRegistryPinned(gpa, io, environ);859865 }860866 861867 // --- Log helper ---

view file

src/output.zig+7 −0
@@ -737,6 +737,13 @@737737     p("{s}all set\n", .{hdr()});738738 }739739 740+// Printed once, before the first search, when the nixpkgs registry still points741+// at a remote URL. Flush so it lands before `nix registry pin` and any results.742+pub fn pinningRegistry() void {743+    p("{s}pinning nixpkgs for fast local search...\n", .{hdr()});744+    flush();745+}746+740747 pub fn setupEnabling() void {741748     p("{s}enabling experimental features\n", .{hdr()});742749 }

view file