Skip to content

Commit fb780a0

Browse files
chrisbbreuerclaude
andcommitted
revert: restore Zig 0.16-dev APIs (will upload dev Zig to pantry)
Reverts the 0.15.1 API downgrade. The repos should target 0.16-dev. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7c996e8 commit fb780a0

4 files changed

Lines changed: 66 additions & 40 deletions

File tree

build.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pub fn build(b: *std.Build) void {
1414
const tests = b.addTest(.{
1515
.root_module = lib_mod,
1616
});
17-
tests.linkLibC();
1817

1918
const run_tests = b.addRunArtifact(tests);
2019

src/config_loader.zig

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ const EnvProcessor = @import("services/env_processor.zig").EnvProcessor;
66
const merge = @import("merge.zig");
77
const utils = @import("utils.zig");
88

9-
/// Get the absolute path of a file relative to a tmpDir
9+
// Zig 0.16+ IO helper
10+
var io_instance: std.Io.Threaded = .init_single_threaded;
11+
fn getIo() std.Io {
12+
return io_instance.io();
13+
}
14+
15+
/// Get the absolute path of a file relative to a tmpDir (Zig 0.16 compat)
1016
fn tmpDirRealPath(allocator: std.mem.Allocator, tmp: *std.testing.TmpDir, sub_path: []const u8) ![]const u8 {
1117
// tmpDir is at .zig-cache/tmp/{sub_path} relative to cwd
1218
const c_realpath = std.c.realpath;
@@ -46,7 +52,7 @@ pub const ConfigLoader = struct {
4652
self: *ConfigLoader,
4753
options: types.LoadOptions,
4854
) !types.UntypedConfigResult {
49-
var sources: std.ArrayList(types.SourceInfo) = .empty;
55+
var sources = std.ArrayList(types.SourceInfo){};
5056
try sources.ensureTotalCapacity(self.allocator, 4);
5157
defer sources.deinit(self.allocator);
5258

@@ -315,9 +321,9 @@ test "loadConfig loads typed config from file" {
315321
var tmp = std.testing.tmpDir(.{});
316322
defer tmp.cleanup();
317323

318-
const file = try tmp.dir.createFile("test.json", .{});
319-
defer file.close();
320-
try file.writeAll("{\"loaded\": true, \"count\": 42}");
324+
const file = try tmp.dir.createFile(getIo(), "test.json", .{});
325+
defer file.close(getIo());
326+
try file.writePositionalAll(getIo(), "{\"loaded\": true, \"count\": 42}", 0);
321327

322328
const cwd = try tmpDirRealPath(allocator, &tmp, ".");
323329
defer allocator.free(cwd);
@@ -345,9 +351,9 @@ test "loadConfig extracts nested key from package.json" {
345351
defer tmp.cleanup();
346352

347353
// Create a package.json with a "den" section
348-
const file = try tmp.dir.createFile("package.json", .{});
349-
defer file.close();
350-
try file.writeAll(
354+
const file = try tmp.dir.createFile(getIo(), "package.json", .{});
355+
defer file.close(getIo());
356+
try file.writePositionalAll(getIo(),
351357
\\{
352358
\\ "name": "my-project",
353359
\\ "version": "1.0.0",
@@ -356,7 +362,7 @@ test "loadConfig extracts nested key from package.json" {
356362
\\ "port": 3000
357363
\\ }
358364
\\}
359-
);
365+
, 0);
360366

361367
const cwd = try tmpDirRealPath(allocator, &tmp, ".");
362368
defer allocator.free(cwd);
@@ -383,9 +389,9 @@ test "loadConfig extracts deeply nested key" {
383389
var tmp = std.testing.tmpDir(.{});
384390
defer tmp.cleanup();
385391

386-
const file = try tmp.dir.createFile("config.json", .{});
387-
defer file.close();
388-
try file.writeAll(
392+
const file = try tmp.dir.createFile(getIo(), "config.json", .{});
393+
defer file.close(getIo());
394+
try file.writePositionalAll(getIo(),
389395
\\{
390396
\\ "tooling": {
391397
\\ "shell": {
@@ -394,7 +400,7 @@ test "loadConfig extracts deeply nested key" {
394400
\\ }
395401
\\ }
396402
\\}
397-
);
403+
, 0);
398404

399405
const cwd = try tmpDirRealPath(allocator, &tmp, ".");
400406
defer allocator.free(cwd);

src/services/env_processor.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub const EnvProcessor = struct {
165165
std.mem.eql(u8, s, "1") or
166166
std.mem.eql(u8, lower, "yes");
167167
}
168+
168169
};
169170

170171
test "EnvProcessor.parseEnvValue parses boolean" {

src/services/file_loader.zig

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,22 @@ const types = @import("../types.zig");
44
const errors = @import("../errors.zig");
55
const utils = @import("../utils.zig");
66

7-
/// Check if a file exists
7+
// Zig 0.16+ IO helper
8+
var io_instance: std.Io.Threaded = .init_single_threaded;
9+
fn getIo() std.Io {
10+
return io_instance.io();
11+
}
12+
13+
/// Check if a file exists using cross-platform Io.Dir
814
fn fileExists(path: []const u8) bool {
9-
const file = std.fs.cwd().openFile(path, .{}) catch return false;
10-
file.close();
15+
const file = std.Io.Dir.cwd().openFile(getIo(), path, .{ .mode = .read_only }) catch return false;
16+
file.close(getIo());
1117
return true;
1218
}
1319

1420
/// Strip single-line (//) and multi-line (/* */) comments from JSON content
1521
fn stripJsonComments(allocator: std.mem.Allocator, content: []const u8) ![]const u8 {
16-
var result: std.ArrayList(u8) = .empty;
22+
var result = std.ArrayList(u8){};
1723
try result.ensureTotalCapacity(allocator, content.len);
1824
errdefer result.deinit(allocator);
1925

@@ -64,7 +70,7 @@ fn stripJsonComments(allocator: std.mem.Allocator, content: []const u8) ![]const
6470
try result.append(allocator, c);
6571
}
6672

67-
return try result.toOwnedSlice(allocator);
73+
return result.toOwnedSlice(allocator);
6874
}
6975

7076
/// File loader service for discovering and loading configuration files
@@ -150,18 +156,33 @@ pub const FileLoader = struct {
150156
return self.loadTypeScriptConfig(path);
151157
}
152158

153-
// Open file
154-
const file = std.fs.cwd().openFile(path, .{}) catch |err| {
159+
// Use cross-platform Io.Dir for file access
160+
const file = std.Io.Dir.cwd().openFile(getIo(), path, .{ .mode = .read_only }) catch |err| {
155161
return switch (err) {
156162
error.FileNotFound => errors.ZigConfigError.ConfigFileNotFound,
157163
error.AccessDenied => errors.ZigConfigError.ConfigFilePermissionDenied,
158164
else => errors.ZigConfigError.ConfigFileInvalid,
159165
};
160166
};
161-
defer file.close();
167+
defer file.close(getIo());
168+
169+
// Read file content using Io.File (cross-platform)
170+
var content = std.ArrayList(u8).empty;
171+
defer content.deinit(self.allocator);
172+
173+
var buf: [4096]u8 = undefined;
174+
while (true) {
175+
const bufs = [_][]u8{&buf};
176+
const n = file.readStreaming(getIo(), &bufs) catch {
177+
return errors.ZigConfigError.ConfigFileInvalid;
178+
};
179+
if (n == 0) break;
180+
content.appendSlice(self.allocator, buf[0..n]) catch {
181+
return errors.ZigConfigError.ConfigFileInvalid;
182+
};
183+
}
162184

163-
// Read file content
164-
const owned_content = file.readToEndAlloc(self.allocator, 1024 * 1024) catch {
185+
const owned_content = content.toOwnedSlice(self.allocator) catch {
165186
return errors.ZigConfigError.ConfigFileInvalid;
166187
};
167188
defer self.allocator.free(owned_content);
@@ -205,17 +226,16 @@ pub const FileLoader = struct {
205226
) catch return errors.ZigConfigError.ConfigFileInvalid;
206227
defer self.allocator.free(script);
207228

208-
// Use std.process.Child to execute bun
209-
const result = std.process.Child.run(.{
210-
.allocator = self.allocator,
229+
// Use cross-platform std.process.run to execute bun
230+
const result = std.process.run(self.allocator, getIo(), .{
211231
.argv = &.{ "bun", "-e", script },
212232
}) catch {
213233
return errors.ZigConfigError.ConfigFileInvalid;
214234
};
215235
defer self.allocator.free(result.stdout);
216236
defer self.allocator.free(result.stderr);
217237

218-
if (result.term != .Exited or result.term.Exited != 0) {
238+
if (result.term != .exited or result.term.exited != 0) {
219239
return errors.ZigConfigError.ConfigFileInvalid;
220240
}
221241

@@ -240,12 +260,12 @@ pub const FileLoader = struct {
240260
/// Get file modification time for cache invalidation
241261
pub fn getModTime(self: *FileLoader, path: []const u8) !i64 {
242262
_ = self;
243-
// Open file and use stat
244-
const file = std.fs.cwd().openFile(path, .{}) catch return error.FileNotFound;
245-
defer file.close();
246-
const stat = try file.stat();
247-
// mtime is in nanoseconds (i128), convert to seconds
248-
return @intCast(@divTrunc(stat.mtime, std.time.ns_per_s));
263+
// Open file using cross-platform Io.Dir and use File.stat
264+
const file = std.Io.Dir.cwd().openFile(getIo(), path, .{ .mode = .read_only }) catch return error.FileNotFound;
265+
defer file.close(getIo());
266+
const stat = try file.stat(getIo());
267+
// mtime is in nanoseconds, convert to seconds
268+
return @intCast(@divTrunc(stat.mtime.nanoseconds, std.time.ns_per_s));
249269
}
250270
};
251271

@@ -274,9 +294,9 @@ test "FileLoader.findConfigFile finds in project root" {
274294
var tmp = std.testing.tmpDir(.{});
275295
defer tmp.cleanup();
276296

277-
const file = try tmp.dir.createFile("test.json", .{});
278-
defer file.close();
279-
try file.writeAll("{}");
297+
const file = try tmp.dir.createFile(getIo(), "test.json", .{});
298+
defer file.close(getIo());
299+
try file.writePositionalAll(getIo(), "{}", 0);
280300

281301
const cwd = try tmpDirRealPath(allocator, &tmp, ".");
282302
defer allocator.free(cwd);
@@ -310,9 +330,9 @@ test "FileLoader.loadConfigFile parses JSON" {
310330
var tmp = std.testing.tmpDir(.{});
311331
defer tmp.cleanup();
312332

313-
const file = try tmp.dir.createFile("test.json", .{});
314-
defer file.close();
315-
try file.writeAll("{\"key\": \"value\"}");
333+
const file = try tmp.dir.createFile(getIo(), "test.json", .{});
334+
defer file.close(getIo());
335+
try file.writePositionalAll(getIo(), "{\"key\": \"value\"}", 0);
316336

317337
const path = try tmpDirRealPath(allocator, &tmp, "test.json");
318338
defer allocator.free(path);

0 commit comments

Comments
 (0)