New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend $SYSTEMD_COLORS to switch colors mode #17702
Conversation
I'd say yes. The envvars are supposed to override autodetection.
No, the failures are unexpected. It is possible that your environment (in particular envvars) is confusing the tests or exposing some bug. It needs to be resolved though. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this approach. But backwards compatibility needs to be preserved, so that things that would be parsed as true before are still parsed as such and cause the optimum color pallete to be enabled. Only select numbers like 256 and 16 should be treated as unique. (Strictly speaking, this too is a break of compatibility, since "256" would be treated as true before, but let's assume that people are unlikely to have used such specific values.) Other numbers should be treated the same as "1" too.
The environment is as clean as it can get: I've made a very minimal Arch Linux installation into a qemu qcow2 image and I have been running it with qemu-kvm. Maybe the VM is causing the failures. |
That's unlikely. How are the tests failing exactly? Did you try running them by hand from the command line: $ build/test-format-table
$ build/test-string-util |
This is the output of the failed tests: Tests output[root@archlinux systemd]# build/test-format-table ONE TWO THREE xxx yyy yes a long field YYY no |
Try running the tests under
Something like this: int getenv_colors(int *res) {
const char *e;
int r, val;
e = getenv("SYSTEMD_COLORS");
if (!e)
return -ENXIO;
r = safe_atoi(e, &val);
if (r < 0) {
r = parse_bool(e, &val);
if (r < 0)
return r;
}
*res = val == 1 ? 256 : val;
return 0;
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i must say i am not a fan of the complexity this adds, for so little reason. but ok.
it's amazing how much energy people can put into things just for the ability to run things with a crazy palette...
Yeah, it's certainly not the most efficient way to solve the "problem": this is mostly a pretext to hack on systemd and learn how to contribute. Btw, my palette is not crazy ;) |
src/basic/terminal-util.c
Outdated
if (cached_colors_enabled < 0) { | ||
cached_colors_enabled = get_color_mode() > 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop unnecessary {}
. Also, please fix the indentation. We use 8ch indentation.
BTW, I think it is not necessary to cache colors_enabled
. How about to introduce an inline function in terminal-util.h:
static inline bool colors_enabled(void) {
return get_color_mode() > 0;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop unnecessary {}. Also, please fix the indentation. We use 8ch indentation.
Sorry, I messed this up. Fixed.
BTW, I think it is not necessary to cache colors_enabled
Wouldn't this result in get_color_mode
being executed much more frequently?
Also, what about underline_enabled
? That it also cached.
@@ -405,7 +405,7 @@ static int write_to_console( | |||
if (show_location) { | |||
const char *lon = "", *loff = ""; | |||
if (show_color) { | |||
lon = ANSI_HIGHLIGHT_YELLOW4; | |||
lon = ansi_highlight_yellow4(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this correct? It is conditioned by show_color
boolean, which may be different from SYSTEMD_COLORS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure but I think it should always match colors_enabled
, which is based on get_color_mode
.
If I'm wrong, there could be a case with no colors even if show_colors
is true, but that requires either NO_COLOR
or SYSTEMD_COLORS=0
, which makes sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yuwata this is the last outstanding comment - any update? Does the explanation make sense?
@@ -1377,15 +1373,15 @@ void get_log_colors(int priority, const char **on, const char **off, const char | |||
|
|||
if (priority <= LOG_ERR) { | |||
if (on) | |||
*on = ANSI_HIGHLIGHT_RED; | |||
*on = ansi_highlight_red(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is this correct?
if (off) | ||
*off = ANSI_NORMAL; | ||
if (highlight) | ||
*highlight = ANSI_HIGHLIGHT; | ||
|
||
} else if (priority <= LOG_WARNING) { | ||
if (on) | ||
*on = ANSI_HIGHLIGHT_YELLOW; | ||
*on = ansi_highlight_yellow(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here.
needs rebase |
looks pretty good to me, just minor nits above |
Almost there. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, something seems wrong. I'm using test-dhcp6-client
as a test.
SYSTEMD_LOG_COLOR=1 SYSTEMD_LOG_LOCATION=1 build/test-dhcp6-client
prints a bunch of lines with the location in yellow.
But SYSTEMD_LOG_COLOR=16 ...
and SYSTEMD_LOG_COLOR=256 ...
both use just the foreground white.
I got the variable name wrong. But it still doesn't seem to work as expected:
SYSTEMD_LOG_COLOR=1 SYSTEMD_COLOR=16 SYSTEMD_LOG_LOCATION=1 build/test-dhcp6-client
and
SYSTEMD_LOG_COLOR=1 SYSTEMD_COLOR=256 SYSTEMD_LOG_LOCATION=1 build/test-dhcp6-client
and
SYSTEMD_LOG_COLOR=1 SYSTEMD_COLOR=0 SYSTEMD_LOG_LOCATION=1 build/test-dhcp6-client
look exactly the same. Is this expected?
This commit extends $SYSTEMD_COLORS to an enum variable (compared to a simple boolean) which specifies the "colors mode". This means that, in addition to disabling colors altogether, it's now possible to restrict the console output to 16 or 256 colors only.
There is no need to cache colors_enabled because the function is now simply calling get_color_mode, which is already cached.
I'll take a look, I've only tested journalctl plus a couple of other tools but not this one. |
lgtm. good to merge, if it works |
tested it and seems to work, including the dhcp test, after fixing the env var name in the cmdlines @keszybz posted. Let's get this baby merged then. |
Follow-up for: systemd#17702 Alsoe, see earlier review comment: systemd#17702 (review)
Follow-up for: #17702 Alsoe, see earlier review comment: #17702 (review)
@keszybz I couldn't figure out what the cause of test failure is. If you're still interested, I created a torrent with the VM disk (about 1GB) and instructions to reproduce. Here's the magnet: |
Follow-up for: #17702 Alsoe, see earlier review comment: systemd/systemd#17702 (review)
Description
This is my attempt at solving #14495 and #13561 trying to make everyone happy.
The idea, initially proposed in #13561 (comment) is to make SYSTEMD_COLOR be 0, 16, or 256 to mean no colors, base 16 ANSI colors or 256 colors respectively.
This way if, you don't like the hardcoded yellow/blue, you can just
export SYSTEMD_COLOR=16
and use your own palette.Things done:
Questions
A bunch of tests is failing, but is already failing on master. I'm not sure whether my machine is at fault but seems unrelated to my changes. Can you confirm this?
As of 18f3bc9, setting SYSTEMD_COLORS overrides all other checks: this implies that escape sequences will be printed even in a pipeline. For example try
env SYSTEMD_COLORS=1 systemd-analyze --help | less
.Is this intended?
Should I write a test for
getenv_int
?cc: @keszybz who liked my proposal