Skip to content
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

remove let-env, focus on mutating $env #9574

Merged
merged 4 commits into from Jun 30, 2023
Merged

Conversation

sophiajt
Copy link
Member

@sophiajt sophiajt commented Jun 30, 2023

Description

For years, Nushell has used let-env to set a single environment variable. As our work on scoping continued, we refined what it meant for a variable to be in scope using let but never updated how let-env would work. Instead, let-env confusingly created mutations to the command's copy of $env.

So, to help fix the mental model and point people to the right way of thinking about what changing the environment means, this PR removes let-env to encourage people to think of it as updating the command's environment variable via mutation.

Before:

let-env FOO = "BAR"

Now:

$env.FOO = "BAR"

It's also a good reminder that the environment owned by the command is in the $env variable rather than global like it is in other shells.

User-Facing Changes

BREAKING CHANGE BREAKING CHANGE

This completely removes let-env FOO = "BAR" so that we can focus on $env.FOO = "BAR".

Tests + Formatting

After / Before Submitting

integration scripts to update:

@sophiajt sophiajt changed the title remove let-env, focus on mutation remove let-env, focus on mutating $env Jun 30, 2023
@amtoine amtoine added pr:breaking-change This PR implies a change affecting users and has to be noted in the release notes environment language labels Jun 30, 2023
Copy link
Member

@amtoine amtoine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now it looks good to me 👌

of course this breaks integration with other tools 👍

@amtoine
Copy link
Member

amtoine commented Jun 30, 2023

@jntrnr, the failing test is here in test_std test_path_add, looks like the behaviour of $env.FUIQW = ... has changed 🤔

@sophiajt
Copy link
Member Author

Looks like starship and virtual already use load-env and aren't affected.

@sophiajt
Copy link
Member Author

atuin looks like it will break: https://github.com/ellie/atuin/blob/main/atuin/src/shell/atuin.nu

Copy link
Member

@amtoine amtoine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i do not understand why we need to use load-env in the last commit 😕

@sophiajt
Copy link
Member Author

@amtoine because the path variable is coming from a variable. $env.$FOO = ... isn't supported, only $env.FOO = ...

@amtoine
Copy link
Member

amtoine commented Jun 30, 2023

@jntrnr, i've added the integration scripts above to the body of the PR 👌

@amtoine
Copy link
Member

amtoine commented Jun 30, 2023

@amtoine because the path variable is coming from a variable. $env.$FOO = ... isn't supported, only $env.FOO = ...

oooooh very good catch 😱 👏 👏
i did not even see the $ 👀

@sophiajt
Copy link
Member Author

Zoxide looks like it will also break: https://github.com/ajeetdsouza/zoxide/blob/main/templates/nushell.txt

@amtoine
Copy link
Member

amtoine commented Jun 30, 2023

i propose to make this a draft to avoid merging the PR before we have fixed the integration scripts 😮

@amtoine amtoine marked this pull request as draft June 30, 2023 17:30
Copy link
Member

@amtoine amtoine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe LetEnvDeprecated should go inside crates/nu-command/src/deprecated/ as the other deprecated commands? 🤔

@sophiajt sophiajt marked this pull request as ready for review June 30, 2023 19:10
@sophiajt sophiajt requested a review from amtoine June 30, 2023 19:24
Copy link
Member

@amtoine amtoine left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks about right to me... LET'S BREAK IT 💪 😤

@sophiajt sophiajt merged commit 4af2436 into nushell:main Jun 30, 2023
20 checks passed
@sophiajt sophiajt deleted the remove_let_env branch June 30, 2023 19:57
amtoine added a commit to amtoine/nu_scripts that referenced this pull request Jul 1, 2023
related to nushell/nushell#9574

Commands used
```nushell
sd --string-mode "let-env " '$env.' **/*
git rst before_v0.60/
```
amtoine added a commit to amtoine/dotfiles that referenced this pull request Jul 1, 2023
amtoine added a commit to amtoine/nu-git-manager that referenced this pull request Jul 1, 2023
amtoine added a commit to amtoine/zellij-layouts that referenced this pull request Jul 1, 2023
amtoine added a commit to amtoine/scripts that referenced this pull request Jul 1, 2023
amtoine added a commit to nushell/nu_scripts that referenced this pull request Jul 1, 2023
related to nushell/nushell#9574

Commands used
```nushell
sd --string-mode "let-env " '$env.' **/*
git rst before_v0.60/
```
@hyiltiz
Copy link
Contributor

hyiltiz commented Jul 5, 2023

This is a great change, thank you! I was getting quite confused, but this also breaks quite some scripts. Since the fix is mechanical, would it be meaningful to produce script.nu.orig -> script.nu by applying the let-env FOO = ... -> $env.FOO = ... conversion automatically to help ease the BREAKING-CHANGE transition. Similar procedure can be used for other breaking changes as well.

@amtoine
Copy link
Member

amtoine commented Jul 6, 2023

This is a great change, thank you! I was getting quite confused, but this also breaks quite some scripts. Since the fix is mechanical, would it be meaningful to produce script.nu.orig -> script.nu by applying the let-env FOO = ... -> $env.FOO = ... conversion automatically to help ease the BREAKING-CHANGE transition. Similar procedure can be used for other breaking changes as well.

a few commands i know that should do this migration 😋

  • sed -i 's/let-env /$env./' ...
  • sd 'let-env ' '$env.' ...
  • open ... | str replace --all --string 'let-env ' '$env.' | save --force ...

i did not try them but i think they should do it 😋

@hyiltiz
Copy link
Contributor

hyiltiz commented Jul 7, 2023

I had an alias alias "go home" = let-env JAVA_HOME = (/usr/libexec/java_home -a x86_64 -v 11) before. After simply rewriting as alias "go home" = $env.JAVA_HOME = (/usr/libexec/java_home -a x86_64 -v 11), I get the helpful message that aliasing BinaryOp is not supported (I really hope aliases are agnostic to the content of what they are being aliased to.)

I can probably work around this by defining go home as a function instead in general, and maybe with the load-env trick, but aliasing env variable updates probably should be possible in a more straightforward way.

$ # create alias then test
$ # ---------------------
$ alias set-py =       $env.PY = (which python)
$ alias set-py =      ($env.PY = (which python))
$ alias set-py =      {$env.PY = (which python)}
$ # all of the above are invalid syntax
$ 
$ alias set-py = do {$env.PY = (which python)}
$ set-py  # should create $env.PY
$ $env.PY # no errors but also does not work since closures don't mutate
$
$ # the one below works as a workaround, though maybe a bit ugly
$ alias set-py = load-env {XY: (which python)}
$ set-py # no error here
$ $env.XY # works!

@amtoine
Copy link
Member

amtoine commented Jul 8, 2023

@hyiltiz
yeah, aliases should be command calls, this is why $env.PY = ... does not work. and do { ... } does not work either because i'd say do is a bit like a keyword?

load-env is a great solution 👌
you can also write a custom def-env command for such things 😋

@hyiltiz
Copy link
Contributor

hyiltiz commented Jul 8, 2023

Is there a benefit for defining it as a command vs. alias, except the fact that in a command there is much larger flexibility to do arbitrarily complex things (may not be desirable since by alias I meant to show the shallowness of implementation).

I'll just use load-env and maybe convert them to def-env if needs arise. Thanks, @amtoine!

@amtoine
Copy link
Member

amtoine commented Jul 9, 2023

Is there a benefit for defining it as a command vs. alias, except the fact that in a command there is much larger flexibility to do arbitrarily complex things (may not be desirable since by alias I meant to show the shallowness of implementation).

maybe @kubouch might have more information about the aliases as he rewrote them completely not so long ago, but i'd say that by design aliases do alias to commands, not language constructs.
e.g. you can alias ll = ls -l because ls -l is a simple command call but you cannot alias foo = if ... because this is not a command 🤔

I'll just use load-env and maybe convert them to def-env if needs arise. Thanks, @amtoine!

yeah, as load-env is a command, it does the trick 😏

JonasLeonhard added a commit to JonasLeonhard/nushell-config that referenced this pull request Jul 13, 2023
@EnricoGhiorzi
Copy link

This did break compatibility with some other tools (I experience it with Starship) because the updated scripts have not been included into a release yet (not to mention it required hand-fixing the env and config files). I guess it's too late now, but instead of turning the old sytnax into a hard error it would have been better to deprecate it (as in, just rise a warning) for some time. Hopefully this will fix itself as the new scripts are released. Overall, not a great user experience.

@amtoine
Copy link
Member

amtoine commented Jul 26, 2023

This did break compatibility with some other tools (I experience it with Starship) because the updated scripts have not been included into a release yet (not to mention it required hand-fixing the env and config files).

yeah, the fix i wrote on the Starship side is ahead the latest release by 7 commits 😭

I guess it's too late now, but instead of turning the old sytnax into a hard error it would have been better to deprecate it (as in, just rise a warning) for some time.

the deprecation system definitely needs love 😌
we will work on this in #9812!

Hopefully this will fix itself as the new scripts are released.

i can confirm you it will 👌
i build Starship from source and it works like a charm with latest release!

Overall, not a great user experience.

again, sorry for the inconvenience...
we are working on release a patch as soon as possible 🤞

@nushell nushell locked as too heated and limited conversation to collaborators Jul 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
environment language pr:breaking-change This PR implies a change affecting users and has to be noted in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants