elves / elvish

Powerful scripting language & versatile interactive shell
https://elv.sh/
BSD 2-Clause "Simplified" License
5.65k stars 299 forks source link

Fixes multihardlink directory styling on unix #1710

Closed delameter closed 1 year ago

delameter commented 1 year ago

Hello.

Encountered strange behaviour of lscolors package regarding multihardlink formatting on unix systems.

It's perfectly normal for a directory to have more than one reference -- that's how Unix filesystem works (as far as I know), e.g. execution of /usr/bin/ls -hn --color / yields:

lrwxrwxrwx   1 0 0    7  1 Jul  2021 bin -> usr/bin
drwxr-xr-x   4 0 0 4.0K 29 Jun 06:36 boot
drwxrwxr-x   2 0 0 4.0K  1 Jul  2021 cdrom
drwxr-xr-x   3 0 0 4.0K 16 Mar 19:47 data
drwxr-xr-x  20 0 0 4.8K 14 Jul 13:12 dev
...

where 2nd column is reference count for each directory.

I've created a real multihardlink file and default ls displays it in red and yellow color (as configured in LS_COLORS env. var):

$ LS_COLORS="mh=1;33;48;5;52:" /usr/bin/ls -l --color

image

However, invoking pkg/cli/lscolors on the same directory results in:

image

That's why I propose to add extra logic into isMultiHardlink() function.


Further investigation showed up that the result also depends on current working directory. Excessive coloring happens when working directory is the same as listing directory, and vanishes when listing directory is different.

image

image

Apparently, that's because GetStyle() expects absolute paths, not relative ones.

xiaq commented 1 year ago

Hmm, interesting. You can't normally create hard links to directories with ln but TIL the nlink field counts all the . and .. references as hard links too. Thanks for the fix. I'll add a regression test for it too.

Further investigation showed up that the result also depends on current working directory. Excessive coloring happens when working directory is the same as listing directory, and vanishes when listing directory is different.

image

image

Apparently, that's because GetStyle() expects absolute paths, not relative ones.

I don't get this part. Your screenshots show a l4 command, which I assume is a program you've built based on the lscolors package. Is there a similar bug in Elvish itself?

delameter commented 1 year ago

I don't get this part. Your screenshots show a l4 command, which I assume is a program you've built based on the lscolors package. Is there a similar bug in Elvish itself?

No, I walked through the code with debugger, and as far as I can tell Elvish uses absolute paths and therefore is not affected by this aspect. I changed my paths to absolute and that solved the 2nd issue.