diff --git a/lib/build_runner.zig b/lib/build_runner.zig index e1c3768048..a1b88f8c0b 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -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.