From 9492cb78ce3a9978d83397c425d255bd4195ea1a Mon Sep 17 00:00:00 2001 From: Celtian Date: Fri, 17 Jul 2026 15:14:49 +0200 Subject: [PATCH] feat(version): version sync replaced --- AGENTS.md | 2 +- build.zig | 15 +++++++++++++++ build.zig.zon | 3 ++- package.json | 2 +- scripts/integration.ts | 7 +++++-- scripts/smoke-package.ts | 8 ++++++-- src/root.zig | 2 +- src/version.zig | 1 - 8 files changed, 31 insertions(+), 9 deletions(-) delete mode 100644 src/version.zig diff --git a/AGENTS.md b/AGENTS.md index c26b8cb..2c2fd6d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ - Use Zig 0.16.0, Node.js 24, and Yarn 1.22.22. - Node is used for development and publishing only; the published command must execute the Zig binary directly. -- Keep version `0.0.1` synchronized in `package.json`, `build.zig.zon`, `src/version.zig`, tests, and documentation until a release change is explicitly requested. +- Treat `package.json` as the sole source of truth for the release version. Keep `build.zig.zon` at the neutral `0.0.0` placeholder and derive build/test/package expectations from `package.json`. - Never change the `build.zig.zon` fingerprint. ## Required validation diff --git a/build.zig b/build.zig index 148c002..b478bb0 100644 --- a/build.zig +++ b/build.zig @@ -3,12 +3,27 @@ const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const package_json = std.Io.Dir.cwd().readFileAlloc( + b.graph.io, + "package.json", + b.allocator, + .limited(64 * 1024), + ) catch @panic("failed to read package.json"); + const package = std.json.parseFromSliceLeaky( + struct { version: []const u8 }, + b.allocator, + package_json, + .{ .ignore_unknown_fields = true }, + ) catch @panic("failed to parse package.json"); + const build_options = b.addOptions(); + build_options.addOption([]const u8, "version", package.version); const lib = b.addModule("quick_commitlint", .{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize, }); + lib.addOptions("build_options", build_options); const cli = b.createModule(.{ .root_source_file = b.path("src/cli.zig"), .target = target, diff --git a/build.zig.zon b/build.zig.zon index 60eeab9..8d254b7 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,12 +1,13 @@ .{ .name = .quick_commitlint, - .version = "0.0.1", + .version = "0.0.0", .fingerprint = 0x2a96102bdeea7bbc, .minimum_zig_version = "0.16.0", .dependencies = .{}, .paths = .{ "build.zig", "build.zig.zon", + "package.json", "src", "LICENSE", "README.md", diff --git a/package.json b/package.json index 7b81f4c..3e13028 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "description": "A very fast native commit message linter built with Zig", "scripts": { "validate": "yarn format:check && yarn typecheck:scripts && yarn build && yarn test && yarn test:integration && yarn test:differential", - "format:check": "zig fmt --check src/root.zig src/main.zig src/cli.zig src/config.zig src/lint.zig src/version.zig build.zig", + "format:check": "zig fmt --check src/root.zig src/main.zig src/cli.zig src/config.zig src/lint.zig build.zig", "typecheck:scripts": "tsc --project scripts/tsconfig.json", "build": "zig build", "build:release": "zig build -Doptimize=ReleaseFast -Dtarget=x86_64-linux -Dcpu=baseline", diff --git a/scripts/integration.ts b/scripts/integration.ts index 3e5e5af..9904949 100644 --- a/scripts/integration.ts +++ b/scripts/integration.ts @@ -1,9 +1,10 @@ import { spawnSync } from 'child_process'; -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'; +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'; import { tmpdir } from 'os'; import { join, resolve } from 'path'; const native = resolve(__dirname, '..', 'zig-out', 'bin', 'quick-commitlint'); +const expectedVersion = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf8')).version; const temp = mkdtempSync(join(tmpdir(), 'quick-commitlint-integration-')); function run(args: string[], input?: string | Buffer, cwd = temp) { @@ -86,7 +87,9 @@ try { const version = run(['--version']); expectStatus(version.status, 0, 'version'); - if (String(version.stdout).trim() !== 'quick-commitlint 0.0.1') throw new Error('Incorrect version output.'); + if (String(version.stdout).trim() !== `quick-commitlint ${expectedVersion}`) { + throw new Error('Incorrect version output.'); + } const help = run(['--help']); expectStatus(help.status, 0, 'help'); diff --git a/scripts/smoke-package.ts b/scripts/smoke-package.ts index f6809ba..b1696f9 100644 --- a/scripts/smoke-package.ts +++ b/scripts/smoke-package.ts @@ -5,9 +5,13 @@ import { join, resolve } from 'path'; const projectRoot = resolve(__dirname, '..'); const distDir = join(projectRoot, 'dist'); +const projectManifest = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8')); const manifest = JSON.parse(readFileSync(join(distDir, 'package.json'), 'utf8')); +const expectedVersion = projectManifest.version; -if (manifest.version !== '0.0.1') throw new Error('Packaged version is not 0.0.1.'); +if (manifest.version !== expectedVersion) { + throw new Error(`Packaged version ${manifest.version} does not match ${expectedVersion}.`); +} if (manifest.bin?.['quick-commitlint'] !== 'bin/quick-commitlint') { throw new Error('Packaged bin does not point directly to the native executable.'); } @@ -36,7 +40,7 @@ try { }); const executable = join(installDir, 'node_modules', '.bin', 'quick-commitlint'); const version = execFileSync(executable, ['--version'], { encoding: 'utf8' }).trim(); - if (version !== 'quick-commitlint 0.0.1') throw new Error(`Unexpected version: ${version}`); + if (version !== `quick-commitlint ${expectedVersion}`) throw new Error(`Unexpected version: ${version}`); } finally { rmSync(tarball, { force: true }); rmSync(installDir, { recursive: true, force: true }); diff --git a/src/root.zig b/src/root.zig index 1a6a6b0..050a641 100644 --- a/src/root.zig +++ b/src/root.zig @@ -1,7 +1,7 @@ //! Fast, dependency-free commit message linting. pub const config = @import("config.zig"); pub const linting = @import("lint.zig"); -pub const version = @import("version.zig").value; +pub const version = @import("build_options").version; test { _ = config; diff --git a/src/version.zig b/src/version.zig deleted file mode 100644 index eca22fb..0000000 --- a/src/version.zig +++ /dev/null @@ -1 +0,0 @@ -pub const value = "0.0.1";