Skip to content

Commit

Permalink
Nushell activation scripts (#2170)
Browse files Browse the repository at this point in the history
  • Loading branch information
elferherrera authored Sep 16, 2021
1 parent 1cc503b commit e0410ca
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 2 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,14 @@ jobs:
run: |
for i in 1 2 3; do
echo "try $i" && \
${{ runner.os == 'Linux' && 'sudo apt-get update -y && sudo apt-get install fish csh' || true}} && \
${{ runner.os == 'macOS' && 'brew install fish tcsh' || true}} && \
${{ runner.os == 'Linux' && 'sudo apt-get update -y && sudo apt-get install fish csh -y' || true }} && \
${{ runner.os == 'Linux' && 'sudo apt-get install curl wget -y' || true }} && \
${{ runner.os == 'Linux' && 'nushell_url=$(curl -s https://api.github.com/repos/nushell/nushell/releases/latest | grep "browser_" | cut -d\" -f4 | grep .tar.gz)' || true }} && \
${{ runner.os == 'Linux' && 'wget -O nushell.tar.gz $nushell_url' || true }} && \
${{ runner.os == 'Linux' && 'tar -zxf nushell.tar.gz --one-top-level=nushell --strip-components=2' || true }} && \
${{ runner.os == 'Linux' && 'sudo cp nushell/nu /usr/bin' || true }} && \
${{ runner.os == 'Windows' && 'choco install nushell' || true }} && \
${{ runner.os == 'macOS' && 'brew update && brew install fish tcsh nushell' || true }} && \
exit 0 || true;
done
exit 1
Expand Down
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ virtualenv.activate =
fish = virtualenv.activation.fish:FishActivator
powershell = virtualenv.activation.powershell:PowerShellActivator
python = virtualenv.activation.python:PythonActivator
nushell = virtualenv.activation.nushell:NushellActivator
virtualenv.create =
venv = virtualenv.create.via_global_ref.venv:Venv
cpython3-posix = virtualenv.create.via_global_ref.builtin.cpython.cpython3:CPython3Posix
Expand Down Expand Up @@ -108,6 +109,7 @@ virtualenv.activation.bash = *.sh
virtualenv.activation.batch = *.bat
virtualenv.activation.cshell = *.csh
virtualenv.activation.fish = *.fish
virtualenv.activation.nushell = *.nu
virtualenv.activation.powershell = *.ps1
virtualenv.seed.wheels.embed = *.whl

Expand Down
2 changes: 2 additions & 0 deletions src/virtualenv/activation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .batch import BatchActivator
from .cshell import CShellActivator
from .fish import FishActivator
from .nushell import NushellActivator
from .powershell import PowerShellActivator
from .python import PythonActivator

Expand All @@ -14,4 +15,5 @@
"PythonActivator",
"BatchActivator",
"FishActivator",
"NushellActivator",
]
28 changes: 28 additions & 0 deletions src/virtualenv/activation/nushell/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from __future__ import absolute_import, unicode_literals

import os

from virtualenv.util.path import Path
from virtualenv.util.six import ensure_text

from ..via_template import ViaTemplateActivator


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

return {
"__VIRTUAL_PROMPT__": "" if self.flag_prompt is None else self.flag_prompt,
"__VIRTUAL_ENV__": ensure_text(str(creator.dest)),
"__VIRTUAL_NAME__": creator.env_name,
"__BIN_NAME__": ensure_text(str(creator.bin_dir.relative_to(creator.dest))),
"__PATH_SEP__": ensure_text(os.pathsep),
"__DEACTIVATE_PATH__": ensure_text(str(Path(dest_folder) / "deactivate.nu")),
}
40 changes: 40 additions & 0 deletions src/virtualenv/activation/nushell/activate.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Setting all environment variables for the venv
let virtual-env = "__VIRTUAL_ENV__"
let bin = "__BIN_NAME__"
let path-sep = "__PATH_SEP__"

let old-path = ($nu.path | str collect ($path-sep))

let venv-path = ([$virtual-env $bin] | path join)
let new-path = ($nu.path | prepend $venv-path | str collect ($path-sep))

# environment variables that will be batched loaded to the virtual env
let new-env = ([
[name, value];
[PATH $new-path]
[_OLD_VIRTUAL_PATH $old-path]
[VIRTUAL_ENV $virtual-env]
])

load-env $new-env

# Creating the new prompt for the session
let virtual_prompt = (if ("__VIRTUAL_PROMPT__" != "") {
"__VIRTUAL_PROMPT__"
} {
$virtual-env | path basename
}
)

# If there is no default prompt, then only the env is printed in the prompt
let new_prompt = (if ( config | select prompt | empty? ) {
($"build-string '(char lparen)' '($virtual_prompt)' '(char rparen) ' ")
} {
($"build-string '(char lparen)' '($virtual_prompt)' '(char rparen) ' (config get prompt | str find-replace "build-string" "")")
})
let-env PROMPT_COMMAND = $new_prompt

# We are using alias as the function definitions because only aliases can be
# removed from the scope
alias pydoc = python -m pydoc
alias deactivate = source "__DEACTIVATE_PATH__"
11 changes: 11 additions & 0 deletions src/virtualenv/activation/nushell/deactivate.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Setting the old path
let path-name = (if ((sys).host.name == "Windows") { "Path" } { "PATH" })
let-env $path-name = $nu.env._OLD_VIRTUAL_PATH

# Unleting the environment variables that were created when activating the env
unlet-env VIRTUAL_ENV
unlet-env _OLD_VIRTUAL_PATH
unlet-env PROMPT_COMMAND

unalias pydoc
unalias deactivate
26 changes: 26 additions & 0 deletions tests/unit/activation/test_nushell.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from __future__ import absolute_import, unicode_literals

import sys

if sys.version_info > (3,):
from shutil import which
else:
from distutils.spawn import find_executable as which


from virtualenv.activation import NushellActivator
from virtualenv.info import IS_WIN


def test_nushell(activation_tester_class, activation_tester):
class Nushell(activation_tester_class):
def __init__(self, session):
cmd = which("nu")
if cmd is None and IS_WIN:
cmd = "c:\\program files\\nu\\bin\\nu.exe"

super(Nushell, self).__init__(NushellActivator, session, cmd, "activate.nu", "nu")

self.unix_line_ending = not IS_WIN

activation_tester(Nushell)

0 comments on commit e0410ca

Please sign in to comment.