refactor(zig-cookbook): adopt Zig 0.16 I/O system#122
Conversation
Refactor main entry points to accept std.process.Init. Migrate file I/O, networking, and crypto operations to use the new std.Io interface. Removes zigcli dependency and bumps minimum Zig version to 0.16.0.
There was a problem hiding this comment.
Code Review
This pull request updates the cookbook examples to be compatible with Zig 0.16.0, migrating from legacy std.fs and std.net APIs to the new std.Io system. Key changes include updating main signatures to accept std.process.Init, utilizing std.Io for file and network operations, and replacing std.Thread.Pool with Io.Group. A compilation error was identified in assets/src/08-02.zig where a union tag was incorrectly cased as exited instead of Exited.
There was a problem hiding this comment.
Pull request overview
This PR migrates the zig-cookbook examples and build harness to Zig 0.16.0, adopting the new std.Io-based I/O model and std.process.Init entrypoint pattern while removing the zigcli dependency.
Changes:
- Bump minimum Zig version to
0.16.0and remove thezigclidependency. - Refactor many example
mainfunctions to acceptstd.process.Initand route allocations/I/O throughinit.gpaandinit.io. - Update filesystem, networking, process spawning, and crypto examples to use Zig 0.16
std.IoAPIs and updated build/link APIs.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| build.zig.zon | Bumps minimum Zig version to 0.16.0 and removes zigcli from dependencies. |
| build.zig | Updates directory iteration to std.Io and adjusts linking/build logic; skips the prior zigcli-dependent example. |
| assets/src/14-03.zig | Switches main to std.process.Init and uses init.gpa for allocations. |
| assets/src/12-03.zig | Switches main to std.process.Init and uses init.gpa. |
| assets/src/12-02.zig | Switches main to std.process.Init and uses init.gpa. |
| assets/src/10-03.zig | Switches main to std.process.Init and uses init.gpa. |
| assets/src/10-02.zig | Updates ZON parsing to allocation-based APIs and frees via zon.parse.free; uses init.gpa. |
| assets/src/10-01.zig | Switches main to std.process.Init and uses init.gpa. |
| assets/src/08-02.zig | Replaces manual child process handling with std.process.run(gpa, io, ...) and frees outputs. |
| assets/src/07-04.zig | Replaces removed std.once with an atomic-based “call once” implementation. |
| assets/src/07-03.zig | Migrates thread pool example to std.Io.Group async/await style. |
| assets/src/07-02.zig | Migrates mutex usage to std.Io.Mutex and threads use init.io. |
| assets/src/06-01.zig | Migrates crypto RNG usage to std.Random.IoSource backed by init.io. |
| assets/src/05-03.zig | Migrates HTTP server example to std.Io.net sockets/streams and io-based readers/writers. |
| assets/src/05-02.zig | Migrates HTTP client example to http.Client configured with { .allocator = gpa, .io = io }. |
| assets/src/05-01.zig | Migrates HTTP client example to http.Client configured with { .allocator = gpa, .io = io }. |
| assets/src/04-03.zig | Migrates UDP example from std.posix socket calls to std.Io.net datagram socket APIs. |
| assets/src/04-02.zig | Migrates TCP client and argv parsing to init.minimal.args and std.Io.net. |
| assets/src/04-01.zig | Migrates TCP server to std.Io.net and stream reader/writer APIs using io. |
| assets/src/03-01.zig | Migrates timing/sleep to std.Io.Clock and Io.sleep. |
| assets/src/02-03.zig | Migrates secure randomness to std.Io.randomSecure and threads io into Argon2 KDF call. |
| assets/src/02-01.zig | Migrates file hashing example to std.Io.File + file.reader(io, ...). |
| assets/src/01-05.zig | Migrates directory walking to std.Io.Dir + walker.next(io) and uses init.gpa. |
| assets/src/01-04.zig | Migrates file existence check to std.Io.Dir.cwd().access(io, ...). |
| assets/src/01-03.zig | Migrates directory walking/stat to std.Io APIs and uses std.Io.Clock for current time. |
| assets/src/01-02.zig | Migrates file operations to std.Io.Dir/std.Io.File APIs and updates mmap flags style. |
| assets/src/01-01.zig | Migrates file reading example to std.Io.Dir/std.Io.File reader APIs using init.io. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Refactor build process to use translate_c for C headers instead of @cImport. Add zigcli dependency and example integration for 13-01. Improve compatibility with Zig 0.16 by adding library wrappers and modular imports. This change streamlines external library handling and facilitates future upgrades.
Clarify that the main branch now tracks Zig 0.16.x instead of 0.15.x. Reflecting this change in both English and Chinese README avoids confusion about current Zig version support and communicates updated compatibility to users and contributors.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 89 out of 90 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const io = b.graph.io; | ||
| const src_dir = try std.Io.Dir.cwd().openDir(io, b.path("assets/src").getPath(b), .{ .iterate = true }); | ||
|
|
||
| const target = b.standardTargetOptions(.{}); | ||
| var it = src_dir.iterate(); |
There was a problem hiding this comment.
src_dir is opened but never closed. In Zig 0.16 std.Io.Dir holds OS resources; please add a defer src_dir.close(io) (and make it var if needed) to avoid leaking a directory handle during zig build (especially noticeable on Windows).
| const name = std.mem.trimEnd(u8, entry.name, ".zig"); | ||
| const exe = b.addExecutable(.{ |
There was a problem hiding this comment.
std.mem.trimEnd(u8, entry.name, ".zig") trims any of the characters in the cutset, not the ".zig" suffix. This can produce wrong example names (e.g. a filename ending with 'g' before the extension would lose that too). Use a suffix-aware approach (e.g. std.mem.trimSuffix / std.fs.path.stem) to reliably strip the extension.
| callOnce(); | ||
| } | ||
|
|
||
| pub fn main() !void { |
There was a problem hiding this comment.
This example still defines pub fn main() !void while the rest of the cookbook is moving to pub fn main(init: std.process.Init) !void (e.g. assets/src/01-01.zig:4, assets/src/05-01.zig:5, assets/src/10-03.zig:6). For consistency with the new entrypoint pattern (and to keep I/O/allocators coming from Init), update this main signature too.
| pub fn main() !void { | |
| pub fn main(init: std.process.Init) !void { | |
| _ = init; |
Ensure src_dir is closed after use to prevent resource leaks. This change improves code safety and reliability during build process by properly managing directory handles.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 93 out of 94 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
build.zig:29
- All examples and
addTranslateCinvocations hardcode.optimize = .Debug, which ignores the user's-Doptimize=setting and makes it impossible to build/run the cookbook in release modes. Consider plumbingconst optimize = b.standardOptimizeOption(.{});through and using it for modules/libraries/translate-c steps.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const std = @import("std"); | ||
| const print = std.debug.print; | ||
| const c = @cImport({ | ||
| @cInclude("libpq-fe.h"); | ||
| }); | ||
| const c = @import("c"); | ||
|
|
There was a problem hiding this comment.
PR description states that main entry points are refactored to accept std.process.Init, but this example still has pub fn main() !void further down in the file. If the intent is to standardize on the new 0.16 I/O setup (init.gpa/init.io), update this example's main signature too; otherwise the PR description should be adjusted.
| const std = @import("std"); | ||
| const print = std.debug.print; | ||
| const c = @cImport({ | ||
| @cInclude("regex.h"); | ||
| // This is our static library. | ||
| @cInclude("regex_slim.h"); | ||
| }); | ||
| const c = @import("c"); | ||
|
|
There was a problem hiding this comment.
PR description states that main entry points are refactored to accept std.process.Init, but this example still has pub fn main() !void further down in the file. If the intent is to standardize on the new 0.16 I/O setup (init.gpa/init.io), update this example's main signature too; otherwise the PR description should be adjusted.
| const io = b.graph.io; | ||
| var src_dir = try std.Io.Dir.cwd().openDir(io, b.path("assets/src").getPath(b), .{ .iterate = true }); |
There was a problem hiding this comment.
src_dir is opened but never closed. Add a defer src_dir.close(io); after openDir to avoid leaking a directory handle during the build (especially important if more directories get opened in the future).
| .dependencies = .{ | ||
| .zigcli = .{ | ||
| .url = "https://github.com/jiacai2050/zigcli/archive/edd29d2fbcf977cae40990e091bfb821712afb48.zip", | ||
| .hash = "zigcli-0.3.1-ORC7jLbOAgCvnBYGJqGslo1s-ujF9cMQ3ux05i1OpBMp", | ||
| .url = "git+https://github.com/jiacai2050/zigcli.git?ref=v0.6.0#621920da8f2235c6b9c15addf353e7747e1e899c", | ||
| .hash = "zigcli-0.6.0-ORC7jHD5BQBipVTQYdQwlRQt-d7uVU_Jlz_HUyDouqpa", | ||
| }, |
There was a problem hiding this comment.
PR description says the zigcli dependency is removed, but build.zig.zon still declares a zigcli dependency (and the examples/build logic still reference it). Either update the PR description, or remove the dependency and adjust the argparse example accordingly.
| const std = @import("std"); | ||
| const c = @cImport({ | ||
| @cInclude("sqlite3.h"); | ||
| }); | ||
| const c = @import("c"); | ||
| const print = std.debug.print; |
There was a problem hiding this comment.
PR description states that main entry points are refactored to accept std.process.Init, but this example still has pub fn main() !void further down in the file. If the intent is to standardize on the new 0.16 I/O setup (init.gpa/init.io), update this example's main signature too; otherwise the PR description should be adjusted.
Refactor main entry points to accept std.process.Init. Migrate file I/O, networking, and crypto operations to use the new std.Io interface. Removes zigcli dependency and bumps minimum Zig version to 0.16.0.