Skip to content

Commit 3d1b9a2

Browse files
committed
feat: version pinning for upgrade
Store the user's original version constraint (pin) in state.json. Upgrade respects pins: nodejs@22 upgrades within 22.x, unpinned packages upgrade to latest. Each installed version is upgraded independently.
1 parent 1245217 commit 3d1b9a2

2 files changed

Lines changed: 15 additions & 27 deletions

File tree

onyx.template.toml

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,6 @@ bin = ["my-tool"]
4141
# Packages required to run. Same format as onyx install.
4242
deps = ["nodejs@>=20", "ruby@3"]
4343

44-
# --- Aliases ---
45-
# Alternative names for this package.
46-
aliases = ["mytool", "mt"]
47-
48-
# --- Cleanup ---
49-
# Paths created at runtime that onyx can remove on uninstall.
50-
51-
[cleanup]
52-
paths = [
53-
"~/.config/my-tool",
54-
"~/.my-tool-history",
55-
]
56-
57-
[cleanup.macos]
58-
paths = [
59-
"~/Library/Application Support/my-tool",
60-
"~/Library/Caches/com.user.my-tool",
61-
"~/Library/Preferences/com.user.my-tool.plist",
62-
]
63-
64-
[cleanup.linux]
65-
paths = [
66-
"~/.local/share/my-tool",
67-
"~/.cache/my-tool",
68-
]
69-
7044
# --- Hints ---
7145
# Optional message shown after install.
7246

src/store.zig

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub const Database = struct {
1717
bins: []const []const u8,
1818
closure: []const []const u8,
1919
active: bool,
20+
pin: ?[]const u8 = null,
2021
ephemeral: bool = false,
2122
last_used: i64 = 0,
2223
};
@@ -106,6 +107,10 @@ pub const Database = struct {
106107
.bool => |b| b,
107108
else => false,
108109
} else false;
110+
const pin: ?[]const u8 = if (ver_obj.get("pin")) |a| switch (a) {
111+
.string => |s| s,
112+
else => null,
113+
} else null;
109114
const last_used: i64 = if (ver_obj.get("last_used")) |a| switch (a) {
110115
.integer => |n| n,
111116
else => 0,
@@ -141,6 +146,7 @@ pub const Database = struct {
141146
.bins = try bins.toOwnedSlice(aa),
142147
.closure = try closure_list.toOwnedSlice(aa),
143148
.active = active,
149+
.pin = pin,
144150
.ephemeral = ephemeral,
145151
.last_used = last_used,
146152
});
@@ -185,6 +191,10 @@ pub const Database = struct {
185191
try w.write(ver.store_path);
186192
try w.objectField("active");
187193
try w.write(ver.active);
194+
if (ver.pin) |pin| {
195+
try w.objectField("pin");
196+
try w.write(pin);
197+
}
188198
if (ver.ephemeral) {
189199
try w.objectField("ephemeral");
190200
try w.write(true);
@@ -221,7 +231,7 @@ pub const Database = struct {
221231
try file.writeAll(json_str);
222232
}
223233

224-
pub fn addVersion(self: *Database, name: []const u8, version: []const u8, store_path: []const u8, bins: []const []const u8, closure: []const []const u8, opts: struct { ephemeral: bool = false }) !void {
234+
pub fn addVersion(self: *Database, name: []const u8, version: []const u8, store_path: []const u8, bins: []const []const u8, closure: []const []const u8, opts: struct { pin: ?[]const u8 = null, ephemeral: bool = false }) !void {
225235
const aa = self._arena.allocator();
226236
const name_d = try aa.dupe(u8, name);
227237
const version_d = try aa.dupe(u8, version);
@@ -244,12 +254,15 @@ pub const Database = struct {
244254

245255
const now: i64 = @intCast(@divTrunc(std.time.nanoTimestamp(), std.time.ns_per_s));
246256

257+
const pin_d = if (opts.pin) |p| try aa.dupe(u8, p) else null;
258+
247259
// Check if version already exists
248260
for (gop.value_ptr.versions.items) |*ver| {
249261
if (std.mem.eql(u8, ver.version, version_d)) {
250262
ver.store_path = store_path_d;
251263
ver.bins = bins_d;
252264
ver.closure = closure_d;
265+
ver.pin = pin_d;
253266
if (opts.ephemeral) ver.last_used = now;
254267
return;
255268
}
@@ -264,6 +277,7 @@ pub const Database = struct {
264277
.bins = bins_d,
265278
.closure = closure_d,
266279
.active = is_active,
280+
.pin = pin_d,
267281
.ephemeral = opts.ephemeral,
268282
.last_used = if (opts.ephemeral) now else 0,
269283
});

0 commit comments

Comments
 (0)