build runner: print to stderr in dumb terminals

Terminal progress is suppressed and instead there is an explicit
handling of printing to stderr, one line per step make() function call.
The output looks very similar to Ninja.

A future commit should add a -q to quiet the output.
This commit is contained in:
Andrew Kelley 2023-03-09 23:56:12 -07:00
parent 097bcca069
commit 7d5bce56e1

View File

@ -278,8 +278,12 @@ pub fn main() !void {
.windows_api => {},
}
var progress: std.Progress = .{ .dont_print_on_dumb = true };
var progress: std.Progress = .{};
const main_progress_node = progress.start("", 0);
if (ttyconf == .no_color) {
progress.timer = null;
progress.terminal = null;
}
builder.debug_log_scopes = debug_log_scopes.items;
builder.resolveInstallPrefix(install_prefix, dir_list);
@ -302,6 +306,9 @@ pub fn main() !void {
.enable_summary = enable_summary,
.ttyconf = ttyconf,
.stderr = stderr,
.step_index = 0,
.step_count = undefined,
};
if (run.max_rss == 0) {
@ -332,6 +339,9 @@ const Run = struct {
enable_summary: ?bool,
ttyconf: std.debug.TTY.Config,
stderr: std.fs.File,
step_count: usize,
step_index: usize,
};
fn runStepNames(
@ -395,7 +405,8 @@ fn runStepNames(
{
defer parent_prog_node.end();
var step_prog = parent_prog_node.start("run steps", step_stack.count());
run.step_count = step_stack.count();
var step_prog = parent_prog_node.start("run steps", run.step_count);
defer step_prog.end();
var wait_group: std.Thread.WaitGroup = .{};
@ -739,10 +750,27 @@ fn workerMakeOneStep(
sub_prog_node.activate();
defer sub_prog_node.end();
// I suspect we will want to pass `b` to make() in a future modification.
// For example, CompileStep does some sus things with modifying the saved
// *Build object in install header steps that might be able to be removed
// by passing the *Build object through the make() functions.
const stderr = run.stderr;
const ttyconf = run.ttyconf;
// If we are unable to print a fancy terminal progress bar, then we resort
// to 1 line printed to stderr for each step, similar to Ninja.
if (ttyconf == .no_color) {
var buf: [120]u8 = undefined;
const step_index = @atomicRmw(usize, &run.step_index, .Add, 1, .Monotonic);
const text = std.fmt.bufPrint(&buf, "[{d}/{d}] Making {s}{s}\n", .{
step_index + 1, run.step_count, s.owner.dep_prefix, s.name,
}) catch |err| switch (err) {
error.NoSpaceLeft => blk: {
buf[buf.len - 4 ..].* = "...\n".*;
break :blk &buf;
},
};
std.debug.getStderrMutex().lock();
defer std.debug.getStderrMutex().unlock();
stderr.writeAll(text) catch {};
}
const make_result = s.make(&sub_prog_node);
// No matter the result, we want to display error/warning messages.
@ -750,9 +778,6 @@ fn workerMakeOneStep(
sub_prog_node.context.lock_stderr();
defer sub_prog_node.context.unlock_stderr();
const stderr = run.stderr;
const ttyconf = run.ttyconf;
for (s.result_error_msgs.items) |msg| {
// Sometimes it feels like you just can't catch a break. Finally,
// with Zig, you can.