-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
ls
: Start fix (see comment) color-term.sh
GNU test
#4867
Conversation
GNU testsuite comparison:
|
GNU testsuite comparison:
|
GNU testsuite comparison:
|
ls
: Start fix (see comment) color-term.sh GNU test
ls
: Start fix (see comment) color-term.sh GNU testls
: Start fix (see comment) color-term.sh
GNU test
MacOS test is failing since macOS does not correctly support "LS_COLORS" env variable and the mac env var LSCOLORS is not supported by underlying crate -> sharkdp/lscolors#55 |
GNU testsuite comparison:
|
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.
Very interesting! I do think it's a bit of a shame that we have to parse the dircolors here. It'd be great if lscolors
supported this.
src/uu/ls/src/ls.rs
Outdated
/// # Returns | ||
/// | ||
/// Boolean | ||
fn check_env_variables_against_dircolors(dircolors: &str) -> bool { |
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 think this name could be more descriptive about what it's checking. If I understand correctly, it's checking that the terminal supports 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 also think the lscolors
crate might be interested in a feature like this. It looks like something they might want to support.
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.
@tertsdiepraam LSCOLORS would need to hardcode the values since DIRCOLORS as in this repo does not exist. I can open an issue ofc.
Back to topic, we are not actually checking against is_terminal
which is already provided in many places, LS
is using the terminal list hardcoded in DIRCOLORS.h
to check if the terminal provided via TERM
environment variable is in that list. Sadly even the --color=always
does this, so it basically works almost like --color=auto
.
In addition to this check LS
and rust LS
are checking for terminal already.
I will think of a more descriptive name, I struggled because the whole topic is verymuch down the rabbit hole.
src/uu/ls/src/ls.rs
Outdated
.map(|x| x.replace('*', ".*")) | ||
.collect::<Vec<String>>(); | ||
let dircolors_set = RegexSet::new(terminals).unwrap(); | ||
dircolors_set.matches(term.as_str()).matched_any() |
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.
Can't we use a glob parser directly, without having to convert to regex?
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.
@tertsdiepraam I will have a look and circle back
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've moved the check to glob, it should be more consistent now
src/uu/ls/src/ls.rs
Outdated
/// | ||
/// Boolean | ||
fn check_env_variables_against_dircolors(dircolors: &str) -> bool { | ||
let ls_colors = env::var("LS_COLORS").unwrap_or(String::new()).is_empty(); |
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.
Are you sure that the case where LS_COLORS
is empty and where it is missing have the same effect?
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.
Hi @tertsdiepraam , sorry for taking so long. I just did the test:
When LS_COLORS
is set and empty or unset -> use TERM or COLORTERM
below only applies when above is true
when TERM
is empty, unset or not in DIRCOLORS.h
and COLORTERM
is empty or unset
do not color even when --color=always
when COLORTERM
has any value or TERM
has a glob value fitting with the table in DIRCOLORS.h
use internal default values for coloring
If you like I can put this in a shell file somewhere and make it a test. I would just need to know where a good space would be.
I think this is OK as long as it looks the same. Maybe we should just patch the GNU tests to match our results in |
This is a bit unfortunate and not really sustainable. Is there any way we can remove this restriction? Maybe we can make the function pure by giving it the env variables as arguments, which we can then test and we add the actual // Use this for testing
fn check_variables_against_dircolors(dircolors: &str, ls_colors: Option<String>, colorterm: Option<String>, term: Option<String>) -> bool {
...
}
// Use this in `ls`
fn check_env_vars(dircolors: &str) {
check_variables_against_dircolors(dircolors: &str, env::var("LS_COLORS"), ...)
} |
I already did some work on nu-ansi-term and lscolors has an open PR to support gnu legacy Mode aka double digit styles and reset before apply. Once it's done we will be able to use that feature here and do not need to change tests. |
@sylvestre We can fix the tests with the nu-ansi-term patch later, but my original comments still hold. |
Hey! Love this work, but I'm marking it as a draft, so that we don't accidentally merge the git dependency. Once |
thank you, it turned out that lscolors and nu-ansi-term were incredible helpful with the changes there and we got this going in a much better way than initially thought. I will update accordingly and ping you once it's in a better state. |
GNU testsuite comparison:
|
GNU testsuite comparison:
|
GNU testsuite comparison:
|
GNU testsuite comparison:
|
Hi, I updated the function to take in env variables as results, so the actual unpacking etc happens inside the function and is tested as well. |
GNU testsuite comparison:
|
GNU testsuite comparison:
|
GNU testsuite comparison:
|
Sweet:
|
GNU testsuite comparison:
|
sorry we didn't merge this yet. I tried to rebase it, let's see if it works |
@alexkunde sorry but do you have plans to finish it? |
no activity for a while, closing |
Fixes GNU test color-term.sh for LS (kind of)
Explaination
ls --color=always
should honor the environment variables LS_COLOR and COLORTERM, if they are not set or empty it should honor the env variable TERM and use the default values for coloring. Additionally for TERM there is a terminal list in DIRCOLORS that needs to be checked and only if the value is in that list, it is allowed. Otherwise, even with --color=always no color should be set.The rust version does not look for any env variables or check the terminal list in DIRCOLOR. This PR will fix it and implement the hirarchy as well as the list check.
I also added tests for the different scenarios.
Beware, they need to be either run withfixedcargo test -- --test-threads=1
orcargo nextest run
otherwise all test will change the env variables at the same time and the tests will fail.Why is GNU test color-term.sh not green?
String Coloring in rust is done via LSCOLOR and nu-ansi-term and they do generally what is expected, but not 100% under the hood.
Test result:
As you can see all 4 tests are doing what they should be doing, but the rust version is using single-digit numbers for text while the gnu version uses double-digit numbers. Additionally the gnu version starts off by resetting any pre-styling, which the rust version does not.
As said it is working as expected but not technically. Hopefully this PR can still make it. For the next step changes on the underlying libraries are needed or an architectural decision to refrain from getting this test green.