authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-10 11:26:54-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-10 17:11:26-08:00
log45ec85173329a62bef54a51603b366771ad89281
tree4580dd08f4c4cc8666837816af97706a69c0bf97
parentdf6aed0fc3a85285ad9bf15c942a66255c2b0b31

zig build: handle stderr more elegantly

* Specifically recognize stderr as a different concept than an error message in Step results. * Display it differently when only stderr occurs but the build proceeds successfully. closes #18473

3 files changed, 19 insertions(+), 6 deletions(-)

lib/build_runner.zig+15-4
...@@ -728,10 +728,15 @@ fn printStepFailure(...@@ -728,10 +728,15 @@ fn printStepFailure(
728 try ttyconf.setColor(stderr, .reset);728 try ttyconf.setColor(stderr, .reset);
729 }729 }
730 try stderr.writeAll("\n");730 try stderr.writeAll("\n");
731 } else {731 } else if (s.result_error_msgs.items.len > 0) {
732 try ttyconf.setColor(stderr, .red);732 try ttyconf.setColor(stderr, .red);
733 try stderr.writeAll(" failure\n");733 try stderr.writeAll(" failure\n");
734 try ttyconf.setColor(stderr, .reset);734 try ttyconf.setColor(stderr, .reset);
735 } else {
736 assert(s.result_stderr.len > 0);
737 try ttyconf.setColor(stderr, .red);
738 try stderr.writeAll(" stderr\n");
739 try ttyconf.setColor(stderr, .reset);
735 }740 }
736}741}
737742
...@@ -918,8 +923,9 @@ fn workerMakeOneStep(...@@ -918,8 +923,9 @@ fn workerMakeOneStep(
918 const show_compile_errors = !run.prominent_compile_errors and923 const show_compile_errors = !run.prominent_compile_errors and
919 s.result_error_bundle.errorMessageCount() > 0;924 s.result_error_bundle.errorMessageCount() > 0;
920 const show_error_msgs = s.result_error_msgs.items.len > 0;925 const show_error_msgs = s.result_error_msgs.items.len > 0;
926 const show_stderr = s.result_stderr.len > 0;
921927
922 if (show_error_msgs or show_compile_errors) {928 if (show_error_msgs or show_compile_errors or show_stderr) {
923 sub_prog_node.context.lock_stderr();929 sub_prog_node.context.lock_stderr();
924 defer sub_prog_node.context.unlock_stderr();930 defer sub_prog_node.context.unlock_stderr();
925931
...@@ -1012,11 +1018,16 @@ fn printErrorMessages(b: *std.Build, failing_step: *Step, run: *const Run) !void...@@ -1012,11 +1018,16 @@ fn printErrorMessages(b: *std.Build, failing_step: *Step, run: *const Run) !void
1012 }1018 }
1013 try ttyconf.setColor(stderr, .reset);1019 try ttyconf.setColor(stderr, .reset);
10141020
1015 // Penultimately, the compilation errors.1021 if (failing_step.result_stderr.len > 0) {
1022 try stderr.writeAll(failing_step.result_stderr);
1023 if (!mem.endsWith(u8, failing_step.result_stderr, "\n")) {
1024 try stderr.writeAll("\n");
1025 }
1026 }
1027
1016 if (!run.prominent_compile_errors and failing_step.result_error_bundle.errorMessageCount() > 0)1028 if (!run.prominent_compile_errors and failing_step.result_error_bundle.errorMessageCount() > 0)
1017 try failing_step.result_error_bundle.renderToWriter(renderOptions(ttyconf), stderr.writer());1029 try failing_step.result_error_bundle.renderToWriter(renderOptions(ttyconf), stderr.writer());
10181030
1019 // Finally, generic error messages.
1020 for (failing_step.result_error_msgs.items) |msg| {1031 for (failing_step.result_error_msgs.items) |msg| {
1021 try ttyconf.setColor(stderr, .red);1032 try ttyconf.setColor(stderr, .red);
1022 try stderr.writeAll("error: ");1033 try stderr.writeAll("error: ");
lib/std/Build/Step.zig+2
...@@ -31,6 +31,7 @@ max_rss: usize,...@@ -31,6 +31,7 @@ max_rss: usize,
3131
32result_error_msgs: std.ArrayListUnmanaged([]const u8),32result_error_msgs: std.ArrayListUnmanaged([]const u8),
33result_error_bundle: std.zig.ErrorBundle,33result_error_bundle: std.zig.ErrorBundle,
34result_stderr: []const u8,
34result_cached: bool,35result_cached: bool,
35result_duration_ns: ?u64,36result_duration_ns: ?u64,
36/// 0 means unavailable or not reported.37/// 0 means unavailable or not reported.
...@@ -164,6 +165,7 @@ pub fn init(options: StepOptions) Step {...@@ -164,6 +165,7 @@ pub fn init(options: StepOptions) Step {
164 },165 },
165 .result_error_msgs = .{},166 .result_error_msgs = .{},
166 .result_error_bundle = std.zig.ErrorBundle.empty,167 .result_error_bundle = std.zig.ErrorBundle.empty,
168 .result_stderr = "",
167 .result_cached = false,169 .result_cached = false,
168 .result_duration_ns = null,170 .result_duration_ns = null,
169 .result_peak_rss = 0,171 .result_peak_rss = 0,
lib/std/Build/Step/Run.zig+2-2
...@@ -1214,7 +1214,7 @@ fn evalZigTest(...@@ -1214,7 +1214,7 @@ fn evalZigTest(
12141214
1215 if (stderr.readableLength() > 0) {1215 if (stderr.readableLength() > 0) {
1216 const msg = std.mem.trim(u8, try stderr.toOwnedSlice(), "\n");1216 const msg = std.mem.trim(u8, try stderr.toOwnedSlice(), "\n");
1217 if (msg.len > 0) try self.step.result_error_msgs.append(arena, msg);1217 if (msg.len > 0) self.step.result_stderr = msg;
1218 }1218 }
12191219
1220 // Send EOF to stdin.1220 // Send EOF to stdin.
...@@ -1344,7 +1344,7 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {...@@ -1344,7 +1344,7 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {
1344 else => true,1344 else => true,
1345 };1345 };
1346 if (stderr_is_diagnostic) {1346 if (stderr_is_diagnostic) {
1347 try self.step.result_error_msgs.append(arena, bytes);1347 self.step.result_stderr = bytes;
1348 }1348 }
1349 };1349 };
13501350