ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.83k stars 2.55k forks source link

build: suggestion to make parallel build output more colorblind friendly #14937

Open slimsag opened 1 year ago

slimsag commented 1 year ago

Zig Version

master

Steps to Reproduce and Observed Behavior

Feel free to disregard/close this issue if you like, I don't mind. Just figured I'd pass along my thoughts.

Right now the color-distinguished output for the parallel builds isn't great for me personally, e.g. someone sent me this screenshot and I wasn't able to tell success, passed, and transitive failure are actually green/yellow/red(?):

image

I have particularly bad colorblindness compared to most others; and no doubt this would look better with the contrast in my terminal compared to theirs. But there is a joke "I can't drive, my hands don't work well" -> "What if we made the steering wheel larger?" about how, frankly, color blind modes suck. Sometimes they help me marginally but for a lot of folks distinguishing things with colors just is not the way their brain is wired.

For me that screenshot above is barely more legible than this binary black/white version:

image

Expected Behavior

What would really help me a lot is if we could include any symbology. Some examples:

Like I said feel free to disregard/close, I realize this could make the output more cluttered. Might help in CI outputs too, though?

andrewrk commented 1 year ago

I think the most important thing is for the failures to stand out; success and transitive failures are uninteresting. Ideally your eyes should jump to

zig test dusk-tests Debug native failure

when looking at the build summary, since that is the most important line (apart from the "build summary" line itself, and the actual error messages above that).

Question for you: does the faded out text really not look faded out to you? Specifically, "transitive failure"

mlugg commented 1 year ago

(Presumably it looks faded out but that's indistinguishable from a lot of colors?)

slimsag commented 1 year ago

^ Yes, honestly just reading quickly I see three colors: bright text, dark text, and the background. The faded-out text does look faded-out.

The primary problem is that transitive failure and failure look identical to all the dark text metadata like 10s MaxRSS:30M etc.

andrewrk commented 1 year ago

I'm thinking maybe we unconditionally replace └─ with └❌.

This has the downside of introducing a dependency on Unicode (the box drawing stuff can be done with DEC terminal codes), but perhaps it is worth it regardless. Related: #14411

InKryption commented 1 year ago

What if using └❌ is made the default behavior, and an option is added to fallback to DEC if necessary?

mitchellh commented 1 year ago

I'm extremely sympathetic to your needs here, but a potentially naive question: Zig is already using palette colors for this (i.e. "red" vs. explicitly specified RGB). In a situation like this, is the expectation that a program output alternate colors or that the person with difficulty seeing the colors alter their terminal emulator's palette? I'm not trying to blame you Stephen, I'm just trying to educate myself.

Second question and a real suggestion: Are there alternate colors either in the 256 color spectrum or RGB spectrum that would work here? The 256-color spectrum is well supported by all terminal emulators:

image

Additionally, pretty much every terminal used today supports 24-bit (RGB) as well: https://en.wikipedia.org/wiki/ANSI_escape_code (grep "24-bit"). It looks like this:

ESC[38;2;⟨r⟩;⟨g⟩;⟨b⟩

I feel like we can maybe just get colors that are friendly to color vision challenges rather than introduce Unicode dependencies.

mlugg commented 1 year ago

Stephen isn't necessarily suggesting using alternate colors:

But there is a joke "I can't drive, my hands don't work well" -> "What if we made the steering wheel larger?" about how, frankly, color blind modes suck. Sometimes they help me marginally but for a lot of folks distinguishing things with colors just is not the way their brain is wired.

Instead, the idea seems to be that color-coding often just doesn't work for color-blind peeps, even if they're recognisable colors, and that having symbolic characters is instead more useful for them, hence the discussion of using Unicode symbols like to differentiate failures.

mitchellh commented 1 year ago

Ah, good call out. Thanks and apologies for not being aware, I'm quiet inexperienced in satisfying these needs in the terminal. In that case, if we're worried about Unicode, you can use DEC Technical Character Set (TCS) multiplication symbol: https://en.wikipedia.org/wiki/Multiplication_sign Switching to the TCS is the same as graphical set, but the special codepage symbol is ASCII <. And the multiplication sign is 0xCB.

We can also just use Unicode, just want to share all possible info I know of.

rohlem commented 1 year ago

Since we all seem to agree that the "ok" entries are not worth looking at (unless you're new to a project, or just added a new test you're now looking for), would it maybe be easiest to just add a flag --hide-success? (And if so, should that maybe become the default?) That would reduce the ~20 lines in the example to the relevant 4, without requiring any new design/workaround ideas. EDIT: Only now found out about --summary=failures - basically I think I'd advocate for this to be the default.

(An alternative option would be to allow hiding child nodes of "all success" branches - that way a failure branch sticks out because of its children. I don't prefer that variant personally, but it might be better for some work flows? idk)

desttinghim commented 1 year ago

I'm thinking maybe we unconditionally replace └─ with └❌.

This has the downside of introducing a dependency on Unicode (the box drawing stuff can be done with DEC terminal codes), but perhaps it is worth it regardless. Related: #14411

Instead of using unicode for this, could we not just output an uppercase X? Admittedly it doesn't look as cool, but it should visually communicate the same info. I suppose it might make output more difficult to read for screen readers, but IDK how they handle the unicode pipes either.

booniepepper commented 1 year ago

For symbols I'd also like to suggest the Japanese convention of circle = success, X = failure. I don't know how well this works across other cultures though.

In addition to adding some riff on symbols, you could make only the failures bold. Successes can be green but not bold.

tycode commented 1 year ago

For symbols I'd also like to suggest the Japanese convention of circle = success, X = failure. I don't know how well this works across other cultures though.

I've previously used a piece of software (proprietary I think; I completely forget what it was, but it must have been some kind of TUI) that comprehensively used the lowercase ASCII letters o, x and v where the user would expect things like tree nodes, bullet points, checkboxes, radio buttons, including tri-state elements. It was a little strange seeing this the first time, but because they consistently used it throughout the product, I got used to it pretty quickly and felt it was a great way of representing these states for an interface that didn't need either Unicode or colors. So something similar could be considered here.

Another possibility, since control codes are already being used to produce colors, would be to use the invert style, so that the word "failure" appears in a box as black-on-red instead of red-on-black.

I also agree we should be hiding successes by default and just outputting a summary. Outputting the biggest single-test memory usage and longest single-test run time might be useful as well, but there's generally no need to show the full list every time.

arukiidou commented 9 months ago

playwright dot reporter shows:

······F·············································

andrewrk commented 9 months ago

Switching to the TCS is the same as graphical set, but the special codepage symbol is ASCII <. And the multiplication sign is 0xCB.

I'm really struggling to understand these instructions. I've spent more time than I care to admit trying to figure this out.

const std = @import("std");
pub fn main() !void {
    std.debug.print("\x1B\x28\x30\x6d\x71\x1B\x28\x42\n", .{});
}

Here's code to print a box-drawing character for example. What do I replace this with to output a multiplication sign?

andrewrk commented 9 months ago

image

@slimsag can I get your opinion on this tiny change?

--- a/lib/build_runner.zig
+++ b/lib/build_runner.zig
@@ -638,7 +638,7 @@ fn printStepStatus(
                     try stderr.writer().print(" {d} skipped", .{s.test_results.skip_count});
                 }
             } else {
-                try stderr.writeAll(" success");
+                try stderr.writeAll(" OK");
             }
             try ttyconf.setColor(stderr, .reset);
             if (s.result_duration_ns) |ns| {
@@ -730,7 +730,7 @@ fn printStepFailure(
         try stderr.writeAll("\n");
     } else if (s.result_error_msgs.items.len > 0) {
         try ttyconf.setColor(stderr, .red);
-        try stderr.writeAll(" failure\n");
+        try stderr.writeAll(" FAIL\n");
         try ttyconf.setColor(stderr, .reset);
     } else {
         assert(s.result_stderr.len > 0);

I'm interested in adding symbology too, just having a bit of trouble trying to figure out how to make these other symbols show up in a reliable way for all terminals.

Feel free to make other suggestions too. You can edit this file without rebuilding the compiler, so it's pretty quick to try things.

perillo commented 9 months ago

... What would really help me a lot is if we could include any symbology. Some examples:

* Include Unicode characters like ✓ ❌ for success/fail

Unfortunately, Unicode symbols like these are not always available. For ❌, see https://www.fileformat.info/info/unicode/char/274c/fontsupport.htm. As an example, ✓ is supported by my terminal font (Source Code Pro) but the more visible ✔ is not.