-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Convert Path to list
in main and preserve case
#14764
base: main
Are you sure you want to change the base?
Conversation
@fdncred While I'm confident that this is going to fix the |
My newly added tests are failing on Windows CI, so it looks like the conversion isn't working properly there. I'll test on Windows locally later. Moving to draft for now. |
I hate it when everything passes except one platform. It's such a pain. |
@fdncred It looks like these (new) failing tests might expose the problem you were having on Mac. Apparently the path conversion still wasn't case-insensitive as we thought, but we didn't have any test in place to cover that particular area. With the new tests in place, it fails, and that's a good thing, IMHO. Working on fixing it to make it truly case-insensitive now. |
"Case-insensitive" isn't the right word - I should get better about distinguishing "case-preserving". The problem here is that Again, the tests are now in place to catch this (which is what kept this one from going green until I got the real fix in). Can you give it another try? |
I still get the same thing on my mac when using my regular configuration. If I use This is what I have in my env.nu for ENV_CONVERSIONS. export-env {
let esep_list_converter = {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | str join (char esep) }
}
let esep_path_converter = {
from_string: { |s| $s | split row (char esep) }
to_string: { |v| $v | path expand | str join (char esep) }
}
$env.ENV_CONVERSIONS = {
PATH: $esep_path_converter
# Path: $esep_path_converter
LS_COLORS: $esep_list_converter
DYLD_FALLBACK_LIBRARY_PATH: $esep_path_converter
# PATHEXT: $esep_list_converter
# PSMODULEPATH: $esep_path_converter
}
} |
I have the same ENV_CONVERSIONS section on my Windows box, and $env.path (any text case) produces a list of paths on the latest main branch. This makes me wonder 2 things.
Also, one more tidbit. |
On Windows, with this PR, |
Hmm. I have a hunch, but I'll have to wait until this afternoon to see if it's on the right track. In the meantime, could you test without a path conversion in |
|
@Bahex I think I see the (or at least part of the) problem. #14591 seems to have the same problem I just fixed in Steps to reproduce: $env.foo = "foo"
$env.ENV_CONVERSIONS = {
foo: {
from_string: {|| '✅'}
to_string: {|| 'N/A'}
}
}
# Correct, since the case of the ENV_CONVERSION variable is the same:
print $"$env.foo should be ✅. $env.foo is ($env.foo)"
# => $env.foo should be ✅. $env.foo is ✅
# Also correct, since the lookup of $env.FOO should match case insensitive to $env.foo
print $"$env.FOO should be ✅. $env.FOO is ($env.FOO)"
# => $env.FOO should be ✅. $env.FOO is ✅
$env.bar = "❌"
$env.ENV_CONVERSIONS = {
BAR: {
from_string: {|| '✅'}
to_string: {|| 'N/A'}
}
}
# `bar` is not converted
print $"$env.bar should be ✅. $env.bar is ($env.bar)"
# => $env.bar should be ✅. $env.bar is ❌
# but `BAR` is a newly created variable by ENV_CONVERSIONS
print $"$env.BAR should be ✅. $env.BAR is ($env.BAR)"
# => $env.BAR should be ✅. $env.BAR is ✅ This will be an issue if anyone has a Not 100% sure that's what @fdncred is running into, but it seems likely given the repro above. |
Ahh, just looked at the source code, I can see where I messed up, I do a case insensitive lookup, but store the new value with the key in |
@Bahex No worries! Obviously it took me a while to find the (same) issue in |
@fdncred Nice-to-have might be for |
@fdncred Ok, I think it's fixed for real this time. Can you throw your config at it to test? There's a chance that there's a breaking change here if you are setting an |
list
in mainlist
in main and preserve case
Still doesn't work but I think I figured out why based on your last comment, "or treating it as a string anywhere in your config". I have the ENV_CONVERSIONS set as above but what I didn't think about until you mentioned it, is I do this in my config.nu to get rid of any duplicate entries in my path. $env.PATH = ($env.PATH | par-each {|r| $r | split row (char esep)} | flatten | uniq | str join (char esep)) If I remove that, it returns path as a list. However, shouldn't we be able to assign items to $env.PATH and have them still return a list without having to do a bunch of list creation/append/prepending? Another way of saying it is that I've used this for a long time and it just recently stopped working. I wonder if we should allow $env.path to be changed from a list to a different type. 🤔 |
In this case, you aren't modifying the list, though. You specifically convert it back from a str join (char esep) Once an environment variable is converted, there isn't anything in place to convert it again. Going back to 0.97.1 (before I started mucking about with it ;-):
Is it possible you just haven't been actively inspecting the type of Repro
let temp_home = (mktemp -d)
$env.XDG_CONFIG_HOME = $temp_home
$env.XDG_DATA_HOME = $temp_home
~/oldnu/nu-0.97.1-x86_64-unknown-linux-gnu/nu
# => No environment config file found at /tmp/tmp.r9CMRnZntc/nushell/env.nu
# => Would you like to create one with defaults (Y/n):
# =>
# => Environment config file created at: /tmp/tmp.r9CMRnZntc/nushell/env.nu
# => No config file found at /tmp/tmp.r9CMRnZntc/nushell/config.nu
# => Would you like to create one with defaults (Y/n):
# =>
# => Config file created at: /tmp/tmp.r9CMRnZntc/nushell/config.nu
# Banner __ ,
$env.PATH | first 5
# => ╭───┬────────────────────────────────────────╮
# => │ 0 │ /home/ntd/.local/share/rust/cargo/bin │
# => │ 1 │ /home/ntd/.local/share/rust/rustup/bin │
# => │ 2 │ /home/ntd/.config/carapace/bin │
# => │ 3 │ /home/ntd/.nix-profile/bin │
# => │ 4 │ /home/ntd/.nix-profile/bin │
# => ╰───┴────────────────────────────────────────╯
$env.PATH = ($env.PATH | par-each {|r| $r | split row (char esep)} | flatten | uniq | str join (char esep))
$env.PATH | str substring 0..100
# => /home/ntd/.local/share/rust/cargo/bin:/home/ntd/.local/share/rust/rustup/bin:/home/ntd/.config/carapa
$env.PATH | describe
# => string
Probably not. Or perhaps there should be logic to run It just doesn't seem that there's ever been any logic along those lines. |
You'd think that things wouldn't work right if it was just a string. Either way, I'm fine with landing this and seeing if anything else breaks. Good work researching and testing to figure out what was going on. |
I need to look up the code-path for that (to satisfy my own curiosity), but it seems to work fine as a string or a list: $env.PATH = "/usr/bin:/usr/sbin"
^ls
# => Works
nu
# => Fails, since cargo/bin is no longer in the path |
@fdncred Ah, we're using the |
nushell/crates/nu-engine/src/env.rs Lines 239 to 257 in dc52a6f
|
Description
Fixes multiple issues related to
ENV_CONVERSION
and path-conversion-to-list.convert_env_values()
, but we found that this causednu -n
to no longer convert the path properly.ENV_CONVERSIONS
have apparently never preserved case, meaning a conversion with a key offoo
would not update$env.FOO
but rather create a new environment variable with a different case.PATH
, but it only worked forPATH
andPath
.convert_env_values()
, which handledENV_CONVERSIONS
was called in multiple places in the startup depending on flags.This PR:
main()
rather than in each potential startup pathget_env_var_insensitive()
functions added in add function to make env vars case-insensitive #14390 to return the name of the environment variable with its original case. This allows code that updates environment variables to preserve the case.ENV_CONVERSIONS
to preserve the case of any updated environment variables. TheENV_CONVERSION
key itself is still case insensitive.PATH
environment variable (normally handled separately, regardless of whether or not there was anENV_CONVERSION
for it).Before
env_convert_values
was run:env.nu
ran, which includednu -c <commandstring>
andnu <script.nu>
nu -n
After
env_convert_values
always runs once inmain()
before any config file is processed or the REPL is startedUser-Facing Changes
Bug fixes
Tests Formatting
toolkit fmt
toolkit clippy
toolkit test
toolkit test stdlib
Added additional tests to prevent future regression.
After Submitting
There is additional cleanup that should probably be done in
convert_env_values()
. This function previously handledENV_CONVERSIONS
, but there is no longer any need for this sinceconvert_env_vars()
runs whenever$env.ENV_CONVERSIONS
changes now.This means that the only relevant task in the old
convert_env_values()
is to convert thePATH
to a list, and ensure that it is a list of strings. It's still calling thefrom_string
conversion on every variable (just once) even though there are noENV_CONVERSIONS
at this point.Leaving that to another PR though, while we get the core issue fixed with this one.