Skip to content

Commit 5ccf069

Browse files
committed
Merge branch 'zig-0.16-upgrade' into yolo
2 parents 10e60ef + 0a55724 commit 5ccf069

55 files changed

Lines changed: 1083 additions & 953 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.zig

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -554,11 +554,11 @@ fn linkCommon(
554554
ts_lib: *std.Build.Step.Compile,
555555
lang_libs: []const *std.Build.Step.Compile,
556556
) void {
557-
compile.linkLibrary(sqlite3_lib);
558-
compile.linkLibrary(vec_static_lib);
559-
compile.linkLibrary(pcre2_lib);
560-
compile.linkLibrary(ts_lib);
561-
for (lang_libs) |lib| compile.linkLibrary(lib);
557+
compile.root_module.linkLibrary(sqlite3_lib);
558+
compile.root_module.linkLibrary(vec_static_lib);
559+
compile.root_module.linkLibrary(pcre2_lib);
560+
compile.root_module.linkLibrary(ts_lib);
561+
for (lang_libs) |lib| compile.root_module.linkLibrary(lib);
562562
}
563563

564564
fn buildTreeSitter(
@@ -569,6 +569,7 @@ fn buildTreeSitter(
569569
const ts_module = b.createModule(.{
570570
.target = target,
571571
.optimize = optimize,
572+
.link_libc = true,
572573
});
573574
const ts_lib = b.addLibrary(.{
574575
.name = "tree_sitter",
@@ -580,7 +581,6 @@ fn buildTreeSitter(
580581
});
581582
ts_module.addIncludePath(b.path("deps/tree-sitter/lib/src"));
582583
ts_module.addIncludePath(b.path("deps/tree-sitter/lib/include"));
583-
ts_lib.linkLibC();
584584
ts_lib.installHeader(b.path("deps/tree-sitter/lib/include/tree_sitter/api.h"), "tree_sitter/api.h");
585585
return ts_lib;
586586
}
@@ -596,6 +596,7 @@ fn buildTreeSitterGrammar(
596596
const module = b.createModule(.{
597597
.target = target,
598598
.optimize = optimize,
599+
.link_libc = true,
599600
});
600601
const lib = b.addLibrary(.{
601602
.name = name,
@@ -613,6 +614,5 @@ fn buildTreeSitterGrammar(
613614
module.addIncludePath(b.path(dir));
614615
module.addIncludePath(b.path("deps/tree-sitter/lib/include"));
615616
module.addIncludePath(b.path("deps/tree-sitter/lib/src"));
616-
lib.linkLibC();
617617
return lib;
618618
}

build.zig.zon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
.{
22
.name = .codescan,
33
.version = "0.1.0",
4-
.minimum_zig_version = "0.15.2",
4+
.minimum_zig_version = "0.16.0",
55
.paths = .{
66
"build.zig",
77
"build.zig.zon",
88
"src",
99
},
1010
.dependencies = .{
1111
.sqlite_vec = .{
12-
.url = "git+https://github.com/pmarreck/sqlite-vec.git#742ac1607d5490c71758c9fde80820387391910d",
13-
.hash = "sqlite_vec-0.1.7-alpha.2-4Cdt0OvwBACYsEQvfmbSw0sUHuXhcwD5PgjGyslHXU2q",
12+
.url = "git+https://github.com/pmarreck/sqlite-vec.git#c9d3630f56637276829d9ab0c54b1116c6d3e2ef",
13+
.hash = "sqlite_vec-0.1.7-alpha.2-4Cdt0CTyBADFzDhhNOTSAUplRsfH1qs-DqwP6FwrZ641",
1414
},
1515
.pcre2 = .{
1616
.url = "https://github.com/pmarreck/pcre2/archive/refs/tags/zig-0.16.0.tar.gz",

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
# Pre-fetch Zig build.zig.zon dependencies for sandboxed builds
2020
sqlite-vec-src = pkgs.fetchgit {
2121
url = "https://github.com/pmarreck/sqlite-vec.git";
22-
rev = "742ac1607d5490c71758c9fde80820387391910d";
23-
hash = "sha256-CFZAditwPGoWpAK7AG8BaxksfxjEzyGdlMvuZPsJ7CQ=";
22+
rev = "c9d3630f56637276829d9ab0c54b1116c6d3e2ef";
23+
hash = "sha256-9MBuzlHICNc0U4TIEEPd0gWAftxllXcU8bhilcaAh+k=";
2424
};
2525
pcre2-src = pkgs.fetchgit {
2626
url = "https://github.com/pmarreck/pcre2.git";
@@ -33,7 +33,7 @@
3333
# so we can pass it via --system to avoid network fetches
3434
zigPkgCache = pkgs.linkFarm "zig-pkg-cache" [
3535
{
36-
name = "sqlite_vec-0.1.7-alpha.2-4Cdt0OvwBACYsEQvfmbSw0sUHuXhcwD5PgjGyslHXU2q";
36+
name = "sqlite_vec-0.1.7-alpha.2-4Cdt0CTyBADFzDhhNOTSAUplRsfH1qs-DqwP6FwrZ641";
3737
path = sqlite-vec-src;
3838
}
3939
{
@@ -48,7 +48,7 @@
4848

4949
src = ./.;
5050

51-
nativeBuildInputs = [ pkgs.zig_0_15 ];
51+
nativeBuildInputs = [ pkgs.zig_0_16 ];
5252

5353
dontConfigure = true;
5454
dontFixup = true;
@@ -80,7 +80,7 @@
8080

8181
devShells.default = pkgs.mkShell {
8282
packages = with pkgs; [
83-
zig_0_15
83+
zig_0_16
8484
jq
8585
luajit
8686
luajitPackages.cjson

src/cli.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ pub fn parse(allocator: std.mem.Allocator, args: []const []const u8) !Parsed {
203203
.type_filter = null,
204204
.lang_filter = null,
205205
.kind_filter = null,
206-
.path_filters = .{},
206+
.path_filters = .empty,
207207
.file_filter = null,
208-
.symbols_files = .{},
208+
.symbols_files = .empty,
209209
.pattern = null,
210210
.include_body = false,
211211
.from_ref = null,
@@ -962,7 +962,7 @@ pub fn parse(allocator: std.mem.Allocator, args: []const []const u8) !Parsed {
962962

963963
if (parsed.command == .search) {
964964
if (!query_parts_inited) {
965-
query_parts = .{};
965+
query_parts = .empty;
966966
query_parts_inited = true;
967967
}
968968
try query_parts.append(allocator, arg);

src/config.zig

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const io_singleton = @import("io_singleton.zig");
23
const cli = @import("cli.zig");
34
const env_expand = @import("env_expand.zig");
45

@@ -76,7 +77,7 @@ pub const default_template =
7677

7778
pub const IgnoreOverride = struct {
7879
language: []const u8,
79-
patterns: std.ArrayListUnmanaged([]const u8) = .{},
80+
patterns: std.ArrayListUnmanaged([]const u8) = .empty,
8081

8182
pub fn deinit(self: *IgnoreOverride, allocator: std.mem.Allocator) void {
8283
for (self.patterns.items) |pattern| allocator.free(pattern);
@@ -132,10 +133,10 @@ pub const Config = struct {
132133
docs_only: ?bool = null,
133134
comments_only: ?bool = null,
134135
include_node_modules: ?bool = null,
135-
ignore_global: std.ArrayListUnmanaged([]const u8) = .{},
136-
always_include: std.ArrayListUnmanaged([]const u8) = .{},
137-
ignore_lang: std.ArrayListUnmanaged(IgnoreOverride) = .{},
138-
lsp_overrides: std.ArrayListUnmanaged(LspOverride) = .{},
136+
ignore_global: std.ArrayListUnmanaged([]const u8) = .empty,
137+
always_include: std.ArrayListUnmanaged([]const u8) = .empty,
138+
ignore_lang: std.ArrayListUnmanaged(IgnoreOverride) = .empty,
139+
lsp_overrides: std.ArrayListUnmanaged(LspOverride) = .empty,
139140
http_host: ?[]const u8 = null,
140141
http_port: ?u16 = null,
141142

@@ -469,9 +470,8 @@ pub fn parseText(allocator: std.mem.Allocator, text: []const u8) !Config {
469470
}
470471

471472
pub fn loadFromPath(allocator: std.mem.Allocator, path: []const u8) !Config {
472-
const file = try std.fs.cwd().openFile(path, .{});
473-
defer file.close();
474-
const data = try file.readToEndAlloc(allocator, 1024 * 1024);
473+
const io = io_singleton.getOrInit();
474+
const data = try std.Io.Dir.cwd().readFileAlloc(io, path, allocator, .limited(1024 * 1024));
475475
defer allocator.free(data);
476476
return parseText(allocator, data);
477477
}
@@ -489,7 +489,7 @@ fn appendPatterns(
489489
value: []const u8,
490490
) !void {
491491
// Split on commas, respecting \, as an escaped literal comma
492-
var buf = std.ArrayListUnmanaged(u8){};
492+
var buf = @as(std.ArrayListUnmanaged(u8), .empty);
493493
defer buf.deinit(allocator);
494494
var i: usize = 0;
495495
while (i < value.len) : (i += 1) {
@@ -523,7 +523,7 @@ fn getOrCreateOverride(
523523
}
524524
try list.append(allocator, .{
525525
.language = try allocator.dupe(u8, lang),
526-
.patterns = .{},
526+
.patterns = .empty,
527527
});
528528
return &list.items[list.items.len - 1];
529529
}
@@ -549,7 +549,7 @@ pub const KV = struct {
549549
/// Keys not found in the original content are appended at the end.
550550
/// Returns a new allocated string with the updated content.
551551
pub fn writeConfigValues(allocator: std.mem.Allocator, content: []const u8, kvs: []const KV) ![]u8 {
552-
var output: std.ArrayListUnmanaged(u8) = .{};
552+
var output: std.ArrayListUnmanaged(u8) = .empty;
553553
defer output.deinit(allocator);
554554

555555
// Track which kvs were matched
@@ -567,9 +567,9 @@ pub fn writeConfigValues(allocator: std.mem.Allocator, content: []const u8, kvs:
567567
var was_matched = false;
568568
for (kvs, 0..) |kv, idx| {
569569
// Match "#key=..." or "# key=..." or "key=..."
570-
const trimmed = std.mem.trimLeft(u8, line, " \t");
570+
const trimmed = std.mem.trimStart(u8, line, " \t");
571571
const after_hash = if (std.mem.startsWith(u8, trimmed, "#"))
572-
std.mem.trimLeft(u8, trimmed[1..], " \t")
572+
std.mem.trimStart(u8, trimmed[1..], " \t")
573573
else
574574
trimmed;
575575

@@ -734,9 +734,9 @@ test "default_template parses without error" {
734734
test "loadFromPath reads file" {
735735
var tmp = std.testing.tmpDir(.{});
736736
defer tmp.cleanup();
737-
try tmp.dir.writeFile(.{ .sub_path = "config", .data = "top=3\n" });
737+
try tmp.dir.writeFile(io_singleton.getOrInit(), .{ .sub_path = "config", .data = "top=3\n" });
738738
const allocator = std.testing.allocator;
739-
const path = try tmp.dir.realpathAlloc(allocator, "config");
739+
const path = try tmp.dir.realPathFileAlloc(io_singleton.getOrInit(), "config", allocator);
740740
defer allocator.free(path);
741741
var cfg = try loadFromPath(allocator, path);
742742
defer cfg.deinit(allocator);

src/diff.zig

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ pub fn generateUnifiedDiff(allocator: std.mem.Allocator, old: []const u8, new: [
5959
const hunk_end_new = @min(last_diff_new.? + context, new_lines.len);
6060

6161
// Build output
62-
var buf = std.ArrayListUnmanaged(u8){};
63-
defer buf.deinit(allocator);
64-
65-
const writer = buf.writer(allocator);
62+
var alloc_writer = std.Io.Writer.Allocating.init(allocator);
63+
defer alloc_writer.deinit();
64+
const writer = &alloc_writer.writer;
6665

6766
// File headers
6867
try writer.print("--- a/{s}\n", .{file_path});
@@ -96,14 +95,12 @@ pub fn generateUnifiedDiff(allocator: std.mem.Allocator, old: []const u8, new: [
9695
try writer.print(" {s}\n", .{old_lines[i]});
9796
}
9897

99-
const result = try allocator.alloc(u8, buf.items.len);
100-
@memcpy(result, buf.items);
101-
return result;
98+
return try alloc_writer.toOwnedSlice();
10299
}
103100

104101
/// Split content into lines (slices into the original content, no copying).
105102
fn splitLines(allocator: std.mem.Allocator, content: []const u8) ![]const []const u8 {
106-
var lines = std.ArrayListUnmanaged([]const u8){};
103+
var lines = @as(std.ArrayListUnmanaged([]const u8), .empty);
107104
defer lines.deinit(allocator);
108105

109106
var start: usize = 0;

src/embedding.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const io_singleton = @import("io_singleton.zig");
23
const embedding_http = @import("embedding_http.zig");
34

45
pub const Embedder = struct {
@@ -88,7 +89,7 @@ test "NullEmbedder returns empty embeddings and free is safe" {
8889

8990

9091
fn envOrDefault(allocator: std.mem.Allocator, key: []const u8, fallback: []const u8) ![]u8 {
91-
const value = std.process.getEnvVarOwned(allocator, key) catch |err| switch (err) {
92+
const value = io_singleton.getEnvVarOwned(allocator, key) catch |err| switch (err) {
9293
error.EnvironmentVariableNotFound => return allocator.dupe(u8, fallback),
9394
else => return err,
9495
};

src/embedding_http.zig

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const io_singleton = @import("io_singleton.zig");
23

34
pub const HttpRequest = struct {
45
method: []const u8,
@@ -62,7 +63,7 @@ pub fn embed(
6263

6364
if (response.status != 200) {
6465
var stderr_buf: [256]u8 = undefined;
65-
var stderr_writer = std.fs.File.stderr().writer(&stderr_buf);
66+
var stderr_writer = std.Io.File.stderr().writer(io_singleton.getOrInit(), &stderr_buf);
6667
const stderr = &stderr_writer.interface;
6768
const preview_len = @min(response.body.len, 500);
6869
_ = stderr.print("error: embedding server returned HTTP {d}\n url: {s}\n model: {s}\n body: {s}{s}\n", .{
@@ -117,7 +118,7 @@ pub fn buildEmbedRequest(
117118
.openai => null,
118119
};
119120
const payload = EmbedRequest{ .model = model, .input = inputs, .keep_alive = effective_keep_alive };
120-
var out: std.io.Writer.Allocating = .init(allocator);
121+
var out: std.Io.Writer.Allocating = .init(allocator);
121122
defer out.deinit();
122123

123124
var stream: std.json.Stringify = .{ .writer = &out.writer, .options = .{ .emit_null_optional_fields = false } };
@@ -306,7 +307,7 @@ pub const StdHttpTransport = struct {
306307
client: std.http.Client,
307308

308309
pub fn init(allocator: std.mem.Allocator) StdHttpTransport {
309-
return .{ .client = .{ .allocator = allocator } };
310+
return .{ .client = .{ .allocator = allocator, .io = io_singleton.getOrInit() } };
310311
}
311312

312313
pub fn deinit(self: *StdHttpTransport) void {
@@ -587,7 +588,7 @@ test "embed uses live Ollama" {
587588
}
588589

589590
fn envOrDefault(allocator: std.mem.Allocator, key: []const u8, fallback: []const u8) ![]u8 {
590-
const value = std.process.getEnvVarOwned(allocator, key) catch |err| switch (err) {
591+
const value = io_singleton.getEnvVarOwned(allocator, key) catch |err| switch (err) {
591592
error.EnvironmentVariableNotFound => return allocator.dupe(u8, fallback),
592593
else => return err,
593594
};

src/env_expand.zig

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,23 @@ const max_depth: u8 = 10;
2222
/// Expand `$VAR` / `${VAR}` / `${VAR:-DEF}` / `${VAR-DEF}` / `$$` references
2323
/// against the process environment. Caller owns the returned slice.
2424
pub fn expand(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
25-
var env = try std.process.getEnvMap(allocator);
26-
defer env.deinit();
27-
return expandWith(allocator, input, &env);
25+
// Use the env map set in main() at startup. Tests use expandWith with an
26+
// explicit env map and don't go through this path.
27+
// For test code paths that reach expand() transitively without setting
28+
// an env map, fall back to a lazy-initialized empty map so test logic
29+
// that doesn't depend on env values still works.
30+
const io_singleton = @import("io_singleton.zig");
31+
const env_map = io_singleton.getEnvMapOrInit(allocator);
32+
return expandWith(allocator, input, env_map);
2833
}
2934

3035
/// Hermetic variant used by tests — pass an explicit EnvMap.
3136
pub fn expandWith(
3237
allocator: std.mem.Allocator,
3338
input: []const u8,
34-
env: *const std.process.EnvMap,
39+
env: *const std.process.Environ.Map,
3540
) ![]u8 {
36-
var out = std.ArrayListUnmanaged(u8){};
41+
var out = @as(std.ArrayListUnmanaged(u8), .empty);
3742
errdefer out.deinit(allocator);
3843
try expandInto(allocator, &out, input, env, 0);
3944
return out.toOwnedSlice(allocator);
@@ -77,7 +82,7 @@ fn expandInto(
7782
allocator: std.mem.Allocator,
7883
out: *std.ArrayListUnmanaged(u8),
7984
input: []const u8,
80-
env: *const std.process.EnvMap,
85+
env: *const std.process.Environ.Map,
8186
depth: u8,
8287
) std.mem.Allocator.Error!void {
8388
if (depth > max_depth) {
@@ -146,7 +151,7 @@ fn expandBracedBody(
146151
allocator: std.mem.Allocator,
147152
out: *std.ArrayListUnmanaged(u8),
148153
body: []const u8,
149-
env: *const std.process.EnvMap,
154+
env: *const std.process.Environ.Map,
150155
depth: u8,
151156
) std.mem.Allocator.Error!void {
152157
if (body.len == 0) return; // `${}` → empty
@@ -194,8 +199,8 @@ fn expandBracedBody(
194199

195200
// ---- Tests ----
196201

197-
fn makeEnv(allocator: std.mem.Allocator, pairs: []const [2][]const u8) !std.process.EnvMap {
198-
var env = std.process.EnvMap.init(allocator);
202+
fn makeEnv(allocator: std.mem.Allocator, pairs: []const [2][]const u8) !std.process.Environ.Map {
203+
var env = std.process.Environ.Map.init(allocator);
199204
errdefer env.deinit();
200205
for (pairs) |p| try env.put(p[0], p[1]);
201206
return env;

0 commit comments

Comments
 (0)