From a9f0e240a5eb978bc37a9a63e279cede80e2c1e5 Mon Sep 17 00:00:00 2001 From: Olivier NOUGUIER Date: Thu, 7 May 2026 08:38:32 +0200 Subject: [PATCH 1/3] build: fix environment handling in runCommandOrPanic Update runCommandOrPanic to properly capture and pass the current process environment to child processes using std.process.Environ.Block and std.Io.Threaded. This replaces the use of page_allocator with the provided allocator for better memory management. --- build.zig | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/build.zig b/build.zig index 4c0f85d..940bda6 100644 --- a/build.zig +++ b/build.zig @@ -139,14 +139,20 @@ fn ensureUiBuildExists() void { } fn runCommandOrPanic(allocator: std.mem.Allocator, argv: []const []const u8) void { - _ = allocator; - const run_allocator = std.heap.page_allocator; - const result = std_compat.process.Child.run(.{ - .allocator = run_allocator, + const c_environ = std.c.environ; + var env_count: usize = 0; + while (c_environ[env_count] != null) : (env_count += 1) {} + const env_block: std.process.Environ.Block = .{ .slice = c_environ[0..env_count :null] }; + + var threaded: std.Io.Threaded = .init(allocator, .{ .environ = .{ .block = env_block } }); + defer threaded.deinit(); + const run_io = threaded.io(); + + const result = std.process.run(allocator, run_io, .{ .argv = argv, }) catch |err| std.debug.panic("failed to run {s}: {s}", .{ argv[0], @errorName(err) }); - defer run_allocator.free(result.stdout); - defer run_allocator.free(result.stderr); + defer allocator.free(result.stdout); + defer allocator.free(result.stderr); switch (result.term) { .exited => |code| { From ae7a9d95e8601879079fa42354b3ac67dcc5b7d6 Mon Sep 17 00:00:00 2001 From: Olivier NOUGUIER Date: Thu, 7 May 2026 09:14:13 +0200 Subject: [PATCH 2/3] fix(runCommandOrPanic): streamline environment handling and process spawning --- build.zig | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/build.zig b/build.zig index 940bda6..787c325 100644 --- a/build.zig +++ b/build.zig @@ -127,9 +127,9 @@ fn createUiAssetsModule(b: *std.Build, embed_ui: bool) *std.Build.Module { fn ensureUiBuildReady(b: *std.Build) void { if (pathExists("ui/build")) return; if (!pathExists("ui/node_modules")) { - runCommandOrPanic(b.allocator, &.{ npmCommand(), "--prefix", "ui", "ci", "--no-audit", "--no-fund" }); + runCommandOrPanic(b, &.{ npmCommand(), "--prefix", "ui", "ci", "--no-audit", "--no-fund" }); } - runCommandOrPanic(b.allocator, &.{ npmCommand(), "--prefix", "ui", "run", "build" }); + runCommandOrPanic(b, &.{ npmCommand(), "--prefix", "ui", "run", "build" }); } fn ensureUiBuildExists() void { @@ -138,28 +138,21 @@ fn ensureUiBuildExists() void { } } -fn runCommandOrPanic(allocator: std.mem.Allocator, argv: []const []const u8) void { - const c_environ = std.c.environ; - var env_count: usize = 0; - while (c_environ[env_count] != null) : (env_count += 1) {} - const env_block: std.process.Environ.Block = .{ .slice = c_environ[0..env_count :null] }; +fn runCommandOrPanic(b: *std.Build, argv: []const []const u8) void { + const io = b.graph.io; - var threaded: std.Io.Threaded = .init(allocator, .{ .environ = .{ .block = env_block } }); - defer threaded.deinit(); - const run_io = threaded.io(); - - const result = std.process.run(allocator, run_io, .{ + var child = std.process.spawn(io, .{ .argv = argv, - }) catch |err| std.debug.panic("failed to run {s}: {s}", .{ argv[0], @errorName(err) }); - defer allocator.free(result.stdout); - defer allocator.free(result.stderr); + .stdin = .ignore, + .stdout = .inherit, + .stderr = .inherit, + }) catch |err| std.debug.panic("failed to spawn {s}: {s}", .{ argv[0], @errorName(err) }); + + const term = child.wait(io) catch |err| std.debug.panic("failed to wait {s}: {s}", .{ argv[0], @errorName(err) }); - switch (result.term) { + switch (term) { .exited => |code| { - if (code == 0) return; - if (result.stdout.len > 0) std.debug.print("{s}", .{result.stdout}); - if (result.stderr.len > 0) std.debug.print("{s}", .{result.stderr}); - std.debug.panic("command failed with exit code {d}: {s}", .{ code, argv[0] }); + if (code != 0) std.debug.panic("command failed with exit code {d}: {s}", .{ code, argv[0] }); }, else => std.debug.panic("command did not exit cleanly: {s}", .{argv[0]}), } From 6e3068e9844d5f5852af5ab2fc8e2e8a0956a920 Mon Sep 17 00:00:00 2001 From: Igor Somov Date: Thu, 7 May 2026 22:12:47 -0300 Subject: [PATCH 3/3] fix(build): preserve build spawn environment --- build.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.zig b/build.zig index 787c325..dba5d9b 100644 --- a/build.zig +++ b/build.zig @@ -143,9 +143,11 @@ fn runCommandOrPanic(b: *std.Build, argv: []const []const u8) void { var child = std.process.spawn(io, .{ .argv = argv, + .environ_map = &b.graph.environ_map, .stdin = .ignore, .stdout = .inherit, .stderr = .inherit, + .create_no_window = true, }) catch |err| std.debug.panic("failed to spawn {s}: {s}", .{ argv[0], @errorName(err) }); const term = child.wait(io) catch |err| std.debug.panic("failed to wait {s}: {s}", .{ argv[0], @errorName(err) });