Skip to content

feat: migrate to Zig 0.16#43

Merged
apotema merged 5 commits into
mainfrom
feat/zig-0.16-migration
May 14, 2026
Merged

feat: migrate to Zig 0.16#43
apotema merged 5 commits into
mainfrom
feat/zig-0.16-migration

Conversation

@apotema

@apotema apotema commented May 14, 2026

Copy link
Copy Markdown
Owner

Summary

Migrates zspec from Zig 0.15 to 0.16.

  • @Type(.{ .@"struct" })@Struct(...) (factory.zig)
  • std.testing.refAllDeclsRecursive → small local implementation (zspec.zig)
  • std.time.Timerclock_gettime-based MonoTimer (runner.zig)
  • std.process.getEnvVarOwnedstd.c.getenv / Win32 fallback (runner.zig)
  • std.fs.Filestd.Io.File with raw libc open/write/close for output paths
  • std.PriorityDequeue migrated to unmanaged API (.empty, push(alloc, ...), popMin)
  • dumpStackTrace now takes *const std.debug.StackTrace
  • std.posix.exitstd.process.exit
  • Stripped source-context viewer that depended on the reworked SelfInfo API
  • ArrayListUnmanaged.empty; std.Io.Writer.Allocating for writers
  • std.time.timestampclock_gettime(.REALTIME) (junit.zig)

Status

  • zig build: ✅ PASS
  • zig build test: ✅ PASS (51/51 lib unit tests + fixture + factory_union + factory_zon + examples — over 110 total)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@apotema

apotema commented May 14, 2026

Copy link
Copy Markdown
Owner Author

@copilot review

Zig 0.16 migration requires CI to run on 0.16.0 too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI commented May 14, 2026

Copy link
Copy Markdown
Contributor

@copilot review

Reviewed at dd3bb5e. I re-checked the branch and ran automated PR validation; with no new code changes in this pass, validation reported no additional issues.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates zspec internals, examples, and CI configuration toward Zig 0.16 compatibility while preserving the custom test runner, factory helpers, and JUnit output support.

Changes:

  • Replaces removed/changed Zig std APIs with local implementations or Zig 0.16 equivalents.
  • Updates runner timing, env access, raw output/JUnit file writing, and stack trace dumping.
  • Adjusts factory struct generation, unmanaged containers, examples, tests, and CI Zig version.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/example_test.zig Updates allocator free slice coercion for Zig 0.16.
src/zspec.zig Adds local recursive declaration referencing helper.
src/runner.zig Migrates exit, output file handling, timer, priority dequeue, env reading, and stack trace dumping.
src/junit.zig Migrates ArrayList/writer usage, timestamping, and JUnit file output.
src/factory.zig Migrates runtime struct creation to @Struct.
examples/fsm_integration_test.zig Updates unmanaged array list initialization.
.github/workflows/coverage.yml Updates coverage workflow Zig version.
.github/workflows/ci.yml Updates CI matrix Zig version.
Comments suppressed due to low confidence (1)

src/runner.zig:635

  • This now dumps every frame directly, so the SmartStackTrace path no longer uses isFrameworkFrame to filter runner/expect/std frames even though the runner and the remaining tests still describe that as its behavior. That regresses the user-facing stack trace signal-to-noise; either preserve the filtering with the new 0.16 APIs or update/remove the dead filtering code and tests.
    const index = std.mem.indexOf(u8, test_name, marker) orelse return false;
    _ = std.fmt.parseInt(u32, test_name[index + marker.len ..], 10) catch return false;
    return true;
}

fn isSetup(t: std.builtin.TestFn) bool {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/example_test.zig
}

// Clean up in reverse order
// Clean up in reverse order. Note: in Zig 0.16 we have to coerce the
Comment thread src/junit.zig
Comment on lines +96 to +105
}

for (self.results.items) |result| {
total_time_ns += result.time_ns;
switch (result.status) {
.failed => failures += 1,
.skipped => skipped += 1,
.passed => {},
}
fn writeAllToPath(path: []const u8, bytes: []const u8) !void {
const native_os = @import("builtin").os.tag;
switch (native_os) {
.windows => {
// Use the Win32 file API directly. `std.c.O` is `void` on
// Windows in 0.16, so we can't reuse the POSIX path here.
const w = std.os.windows;
const k32 = struct {
Comment thread src/junit.zig
Comment on lines 80 to +90

pub fn addResult(self: *JUnitWriter, result: TestResult) !void {
try self.results.append(self.allocator, result);
}

pub fn writeToFile(self: *JUnitWriter, path: []const u8) !void {
const file = try std.fs.cwd().createFile(path, .{});
defer file.close();
// Build the XML fully in memory, then dump via the libc file descriptor
// API. Doing the entire I/O dance via `std.Io` would require plumbing an
// `Io` instance through the test runner, which is overkill here.
var aw: std.Io.Writer.Allocating = .init(self.allocator);
defer aw.deinit();
Comment thread src/runner.zig
Comment on lines +513 to 519
_ = slow.popMin();
slow.push(self.allocator, TestInfo{ .ns = ns, .name = test_name }) catch @panic("failed to track test timing");
return ns;
}

fn display(self: *SlowTracker, printer: Printer) !void {
var slow = self.slowest;
Comment thread src/junit.zig
Comment on lines +117 to +123
lpBuffer: [*]const u8,
nNumberOfBytesToWrite: w.DWORD,
lpNumberOfBytesWritten: *w.DWORD,
lpOverlapped: ?*anyopaque,
) callconv(.winapi) w.BOOL;
};
const GENERIC_WRITE: w.DWORD = 0x40000000;
apotema and others added 2 commits May 14, 2026 10:40
- example_test: reverse iteration to match the comment.
- junit.zig: corrected Windows-vs-POSIX implementation comment.
- junit.zig: added writeToFile test coverage (success + error).
- runner.zig: distinguish missing vs empty env vars on Windows via GetLastError.
- junit.zig: reject paths containing interior NUL bytes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Release version bump for the Zig 0.16 migration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@apotema apotema merged commit 88905b0 into main May 14, 2026
4 checks passed
@apotema apotema deleted the feat/zig-0.16-migration branch May 14, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants