d598fb1dd67b
bump build.zig.zon .version to match VERSION and add zon/VERSION sync-check test (NINA-018)
- time
- 2026-07-02 14:40 UTC · 3 months ago
- machine
- koh2
- agent
- claude-sonnet-5
- session
- fable audit fix — version sync
- parent
- 2b98515f8dae
↓ nina-d598fb1d.tar.gzatlas at this save
files changed3 files
build.zig+4 −0build.zig.zon+1 −1src/version.zig+24 −1build.zig+4 −0
@@ -21,6 +21,10 @@2121 // lives outside src/, so it can't be @embedFile'd from within the src/2222 // module's package boundary.2323 options.addOption([]const u8, "readme_path", b.pathJoin(&.{ b.build_root.path.?, "README.md" }));24+ // Absolute path to build.zig.zon, baked in the same way as readme_path so25+ // a test can confirm its hand-maintained `.version` field (a kepr-publishing26+ // fallback if VERSION is ever lost, per NINA-018) hasn't drifted from VERSION.27+ options.addOption([]const u8, "zon_path", b.pathJoin(&.{ b.build_root.path.?, "build.zig.zon" }));2428 2529 const exe = b.addExecutable(.{2630 .name = "nina",build.zig.zon+1 −1
@@ -9,7 +9,7 @@99 .name = .nina,1010 // This is a [Semantic Version](https://semver.org/).1111 // In a future version of Zig it will be used for package deduplication.12- .version = "3.4.3",12+ .version = "3.4.13",1313 // Together with name, this represents a globally unique package1414 // identifier. This field is generated by the Zig toolchain when the1515 // package is first created, and then *never changes*. This allowssrc/version.zig+24 −1
@@ -1,6 +1,8 @@1+const std = @import("std");12 const builtin = @import("builtin");3+const build_options = @import("build_options");24 3-pub const VERSION = @import("build_options").version;5+pub const VERSION = build_options.version;46 57 pub const PLATFORM: []const u8 = switch (builtin.os.tag) {68 .macos => switch (builtin.cpu.arch) {@@ -15,3 +17,24 @@1517 },1618 else => "unsupported",1719 };20+21+// NINA-018 drift guard: build.zig.zon's `.version` field is a hand-maintained22+// fallback the kepr publishing pipeline uses if VERSION is ever lost, so it23+// must never silently drift from the real VERSION file. build.zig.zon lives24+// outside src/'s package boundary, so it's read at its build-time-baked25+// absolute path (build_options.zon_path, same trick as man.zig's readme_path)26+// rather than @embedFile'd.27+test "build.zig.zon .version matches VERSION" {28+ const gpa = std.testing.allocator;29+ const zon = try std.Io.Dir.readFileAlloc(.cwd(), std.testing.io, build_options.zon_path, gpa, .unlimited);30+ defer gpa.free(zon);31+32+ const needle = ".version = \"";33+ const start = (std.mem.indexOf(u8, zon, needle) orelse34+ return error.VersionFieldNotFound) + needle.len;35+ const end = std.mem.indexOfScalarPos(u8, zon, start, '"') orelse36+ return error.VersionFieldNotFound;37+ const zon_version = zon[start..end];38+39+ try std.testing.expectEqualStrings(VERSION, zon_version);40+}