diff --git a/docs/changelog/2422.feature.rst b/docs/changelog/2422.feature.rst new file mode 100644 index 000000000..e4a1fd516 --- /dev/null +++ b/docs/changelog/2422.feature.rst @@ -0,0 +1 @@ +Change Nushell activation script to be a module meant to be activated as an overlay. diff --git a/src/virtualenv/activation/nushell/__init__.py b/src/virtualenv/activation/nushell/__init__.py index 839c19c26..72640a2e8 100644 --- a/src/virtualenv/activation/nushell/__init__.py +++ b/src/virtualenv/activation/nushell/__init__.py @@ -1,4 +1,3 @@ -import os from pathlib import Path from ..via_template import ViaTemplateActivator @@ -7,20 +6,13 @@ class NushellActivator(ViaTemplateActivator): def templates(self): yield Path("activate.nu") - yield Path("deactivate.nu") - - def replacements(self, creator, dest_folder): - # Due to nushell scoping, it isn't easy to create a function that will - # deactivate the environment. For that reason a __DEACTIVATE_PATH__ - # replacement pointing to the deactivate.nu file is created + def replacements(self, creator, dest_folder): # noqa: U100 return { "__VIRTUAL_PROMPT__": "" if self.flag_prompt is None else self.flag_prompt, "__VIRTUAL_ENV__": str(creator.dest), "__VIRTUAL_NAME__": creator.env_name, "__BIN_NAME__": str(creator.bin_dir.relative_to(creator.dest)), - "__PATH_SEP__": os.pathsep, - "__DEACTIVATE_PATH__": str(Path(dest_folder) / "deactivate.nu"), } diff --git a/src/virtualenv/activation/nushell/activate.nu b/src/virtualenv/activation/nushell/activate.nu index 48c85b488..c5568c9a5 100644 --- a/src/virtualenv/activation/nushell/activate.nu +++ b/src/virtualenv/activation/nushell/activate.nu @@ -1,5 +1,12 @@ -# This command prepares the required environment variables -def-env activate-virtualenv [] { +# virtualenv activation module +# Activate with `overlay use activate.nu` +# Deactivate with `deactivate`, as usual +# +# To customize the overlay name, you can call `overlay use activate.nu as foo`, +# but then simply `deactivate` won't work because it is just an alias to hide +# the "activate" overlay. You'd need to call `overlay hide foo` manually. + +export-env { def is-string [x] { ($x | describe) == 'string' } @@ -8,10 +15,10 @@ def-env activate-virtualenv [] { $name in (env).name } - let is_windows = ((sys).host.name | str downcase) == 'windows' + let is_windows = ($nu.os-info.name | str downcase) == 'windows' let virtual_env = '__VIRTUAL_ENV__' let bin = '__BIN_NAME__' - let path_sep = '__PATH_SEP__' + let path_sep = (char esep) let path_name = if $is_windows { if (has-env 'Path') { 'Path' @@ -50,7 +57,7 @@ def-env activate-virtualenv [] { } # Back up the old prompt builder - let old_prompt_command = if (has-env 'VIRTUAL_ENV') && (has-env '_OLD_PROMPT_COMMAND') { + let old_prompt_command = if (has-env 'VIRTUAL_ENV') and (has-env '_OLD_PROMPT_COMMAND') { $env._OLD_PROMPT_COMMAND } else { if (has-env 'PROMPT_COMMAND') { @@ -71,8 +78,8 @@ def-env activate-virtualenv [] { { $'($virtual_prompt)' } } - # Environment variables that will be batched loaded to the virtual env - let new_env = { + # Environment variables that will be loaded as the virtual env + load-env { $path_name : $new_path VIRTUAL_ENV : $virtual_env _OLD_VIRTUAL_PATH : ($old_path | str collect $path_sep) @@ -80,13 +87,7 @@ def-env activate-virtualenv [] { PROMPT_COMMAND : $new_prompt VIRTUAL_PROMPT : $virtual_prompt } - - # Activate the environment variables - load-env $new_env } -# Activate the virtualenv -activate-virtualenv - -alias pydoc = python -m pydoc -alias deactivate = source '__DEACTIVATE_PATH__' +export alias pydoc = python -m pydoc +export alias deactivate = overlay hide activate diff --git a/src/virtualenv/activation/nushell/deactivate.nu b/src/virtualenv/activation/nushell/deactivate.nu deleted file mode 100644 index 4dd132c34..000000000 --- a/src/virtualenv/activation/nushell/deactivate.nu +++ /dev/null @@ -1,32 +0,0 @@ -def-env deactivate-virtualenv [] { - def has-env [name: string] { - $name in (env).name - } - - let is_windows = ((sys).host.name | str downcase) == 'windows' - - let path_name = if $is_windows { - if (has-env 'Path') { - 'Path' - } else { - 'PATH' - } - } else { - 'PATH' - } - - load-env { $path_name : $env._OLD_VIRTUAL_PATH } - - let-env PROMPT_COMMAND = $env._OLD_PROMPT_COMMAND - - # Hiding the environment variables that were created when activating the env - hide _OLD_VIRTUAL_PATH - hide _OLD_PROMPT_COMMAND - hide VIRTUAL_ENV - hide VIRTUAL_PROMPT -} - -deactivate-virtualenv - -hide pydoc -hide deactivate diff --git a/tests/unit/activation/test_nushell.py b/tests/unit/activation/test_nushell.py index a778d4975..cf5886a0c 100644 --- a/tests/unit/activation/test_nushell.py +++ b/tests/unit/activation/test_nushell.py @@ -13,9 +13,16 @@ def __init__(self, session): super().__init__(NushellActivator, session, cmd, "activate.nu", "nu") + self.activate_cmd = "overlay use" self.unix_line_ending = not IS_WIN def print_prompt(self): return r"$env.VIRTUAL_PROMPT" + def activate_call(self, script): + # Commands are called without quotes in Nushell + cmd = self.activate_cmd + scr = self.quote(str(script)) + return f"{cmd} {scr}".strip() + activation_tester(Nushell)