Windows: fix pwsh env activate/deactivate; load/unload (#39118)

These commands are currently broken on powershell (Windows) due to
improper use of the InvokeCommand commandlet and a lack of direct
support for the `--pwsh` argument in `spack load`, `spack unload`,
and `spack env deactivate`.
This commit is contained in:
John W. Parent 2023-09-01 14:36:27 -04:00 committed by GitHub
parent b72a268bc5
commit ca872f9c34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 62 additions and 21 deletions

View file

@ -39,6 +39,20 @@ function Read-SpackArgs {
return $SpackCMD_params, $SpackSubCommand, $SpackSubCommandArgs return $SpackCMD_params, $SpackSubCommand, $SpackSubCommandArgs
} }
function Set-SpackEnv {
# This method is responsible
# for processing the return from $(spack <command>)
# which are returned as System.Object[]'s containing
# a list of env commands
# Invoke-Expression can only handle one command at a time
# so we iterate over the list to invoke the env modification
# expressions one at a time
foreach($envop in $args[0]){
Invoke-Expression $envop
}
}
function Invoke-SpackCD { function Invoke-SpackCD {
if (Compare-CommonArgs $SpackSubCommandArgs) { if (Compare-CommonArgs $SpackSubCommandArgs) {
python $Env:SPACK_ROOT/bin/spack cd -h python $Env:SPACK_ROOT/bin/spack cd -h
@ -79,7 +93,7 @@ function Invoke-SpackEnv {
} }
else { else {
$SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params env activate "--pwsh" $SubCommandSubCommandArgs) $SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params env activate "--pwsh" $SubCommandSubCommandArgs)
$ExecutionContext.InvokeCommand($SpackEnv) Set-SpackEnv $SpackEnv
} }
} }
"deactivate" { "deactivate" {
@ -90,8 +104,8 @@ function Invoke-SpackEnv {
python $Env:SPACK_ROOT/bin/spack env deactivate -h python $Env:SPACK_ROOT/bin/spack env deactivate -h
} }
else { else {
$SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params env deactivate --pwsh) $SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params env deactivate "--pwsh")
$ExecutionContext.InvokeCommand($SpackEnv) Set-SpackEnv $SpackEnv
} }
} }
default {python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand $SpackSubCommandArgs} default {python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand $SpackSubCommandArgs}
@ -107,8 +121,9 @@ function Invoke-SpackLoad {
python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand $SpackSubCommandArgs python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand $SpackSubCommandArgs
} }
else { else {
# python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand "--pwsh" $SpackSubCommandArgs
$SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand "--pwsh" $SpackSubCommandArgs) $SpackEnv = $(python $Env:SPACK_ROOT/bin/spack $SpackCMD_params $SpackSubCommand "--pwsh" $SpackSubCommandArgs)
$ExecutionContext.InvokeCommand($SpackEnv) Set-SpackEnv $SpackEnv
} }
} }

View file

@ -239,6 +239,13 @@ def env_deactivate_setup_parser(subparser):
const="bat", const="bat",
help="print bat commands to activate the environment", help="print bat commands to activate the environment",
) )
shells.add_argument(
"--pwsh",
action="store_const",
dest="shell",
const="pwsh",
help="print pwsh commands to activate the environment",
)
def env_deactivate(args): def env_deactivate(args):

View file

@ -52,6 +52,13 @@ def setup_parser(subparser):
const="bat", const="bat",
help="print bat commands to load the package", help="print bat commands to load the package",
) )
shells.add_argument(
"--pwsh",
action="store_const",
dest="shell",
const="pwsh",
help="print pwsh commands to load the package",
)
subparser.add_argument( subparser.add_argument(
"--first", "--first",

View file

@ -51,6 +51,13 @@ def setup_parser(subparser):
const="bat", const="bat",
help="print bat commands to load the package", help="print bat commands to load the package",
) )
shells.add_argument(
"--pwsh",
action="store_const",
dest="shell",
const="pwsh",
help="print pwsh commands to load the package",
)
subparser.add_argument( subparser.add_argument(
"-a", "--all", action="store_true", help="unload all loaded Spack packages" "-a", "--all", action="store_true", help="unload all loaded Spack packages"

View file

@ -43,7 +43,7 @@ def activate_header(env, shell, prompt=None):
# TODO: despacktivate # TODO: despacktivate
# TODO: prompt # TODO: prompt
elif shell == "pwsh": elif shell == "pwsh":
cmds += "$Env:SPACK_ENV=%s\n" % env.path cmds += "$Env:SPACK_ENV='%s'\n" % env.path
else: else:
if "color" in os.getenv("TERM", "") and prompt: if "color" in os.getenv("TERM", "") and prompt:
prompt = colorize("@G{%s}" % prompt, color=True, enclose=True) prompt = colorize("@G{%s}" % prompt, color=True, enclose=True)
@ -82,7 +82,7 @@ def deactivate_header(shell):
# TODO: despacktivate # TODO: despacktivate
# TODO: prompt # TODO: prompt
elif shell == "pwsh": elif shell == "pwsh":
cmds += "Remove-Item Env:SPACK_ENV" cmds += "Set-Item -Path Env:SPACK_ENV\n"
else: else:
cmds += "if [ ! -z ${SPACK_ENV+x} ]; then\n" cmds += "if [ ! -z ${SPACK_ENV+x} ]; then\n"
cmds += "unset SPACK_ENV; export SPACK_ENV;\n" cmds += "unset SPACK_ENV; export SPACK_ENV;\n"

View file

@ -172,8 +172,8 @@ def test_escape_double_quotes_in_shell_modifications():
assert r'set "VAR=$PATH;$ANOTHER_PATH"' in cmds assert r'set "VAR=$PATH;$ANOTHER_PATH"' in cmds
assert r'set "QUOTED_VAR="MY_VAL"' in cmds assert r'set "QUOTED_VAR="MY_VAL"' in cmds
cmds = to_validate.shell_modifications(shell="pwsh") cmds = to_validate.shell_modifications(shell="pwsh")
assert r"$Env:VAR=$PATH;$ANOTHER_PATH" in cmds assert "$Env:VAR='$PATH;$ANOTHER_PATH'" in cmds
assert r'$Env:QUOTED_VAR="MY_VAL"' in cmds assert "$Env:QUOTED_VAR='\"MY_VAL\"'" in cmds
else: else:
cmds = to_validate.shell_modifications() cmds = to_validate.shell_modifications()
assert 'export VAR="$PATH:$ANOTHER_PATH"' in cmds assert 'export VAR="$PATH:$ANOTHER_PATH"' in cmds

View file

@ -47,7 +47,7 @@
"csh": "setenv {0} {1};\n", "csh": "setenv {0} {1};\n",
"fish": "set -gx {0} {1};\n", "fish": "set -gx {0} {1};\n",
"bat": 'set "{0}={1}"\n', "bat": 'set "{0}={1}"\n',
"pwsh": "$Env:{0}={1}\n", "pwsh": "$Env:{0}='{1}'\n",
} }
@ -56,7 +56,7 @@
"csh": "unsetenv {0};\n", "csh": "unsetenv {0};\n",
"fish": "set -e {0};\n", "fish": "set -e {0};\n",
"bat": 'set "{0}="\n', "bat": 'set "{0}="\n',
"pwsh": "Remove-Item Env:{0}\n", "pwsh": "Set-Item -Path Env:{0}\n",
} }
@ -429,7 +429,7 @@ class RemovePath(NameValueModifier):
def execute(self, env: MutableMapping[str, str]): def execute(self, env: MutableMapping[str, str]):
tty.debug(f"RemovePath: {self.name}-{str(self.value)}", level=3) tty.debug(f"RemovePath: {self.name}-{str(self.value)}", level=3)
environment_value = env.get(self.name, "") environment_value = env.get(self.name, "")
directories = environment_value.split(self.separator) if environment_value else [] directories = environment_value.split(self.separator)
directories = [ directories = [
path_to_os_path(os.path.normpath(x)).pop() path_to_os_path(os.path.normpath(x)).pop()
for x in directories for x in directories
@ -724,11 +724,10 @@ def shell_modifications(
cmds += _SHELL_UNSET_STRINGS[shell].format(name) cmds += _SHELL_UNSET_STRINGS[shell].format(name)
else: else:
if sys.platform != "win32": if sys.platform != "win32":
cmd = _SHELL_SET_STRINGS[shell].format( new_env_name = double_quote_escape(new_env[name])
name, double_quote_escape(new_env[name])
)
else: else:
cmd = _SHELL_SET_STRINGS[shell].format(name, new_env[name]) new_env_name = new_env[name]
cmd = _SHELL_SET_STRINGS[shell].format(name, new_env_name)
cmds += cmd cmds += cmd
return cmds return cmds

View file

@ -1012,7 +1012,7 @@ _spack_env_activate() {
} }
_spack_env_deactivate() { _spack_env_deactivate() {
SPACK_COMPREPLY="-h --help --sh --csh --fish --bat" SPACK_COMPREPLY="-h --help --sh --csh --fish --bat --pwsh"
} }
_spack_env_create() { _spack_env_create() {
@ -1304,7 +1304,7 @@ _spack_list() {
_spack_load() { _spack_load() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help --sh --csh --fish --bat --first --only --list" SPACK_COMPREPLY="-h --help --sh --csh --fish --bat --pwsh --first --only --list"
else else
_installed_packages _installed_packages
fi fi
@ -1922,7 +1922,7 @@ _spack_unit_test() {
_spack_unload() { _spack_unload() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help --sh --csh --fish --bat -a --all" SPACK_COMPREPLY="-h --help --sh --csh --fish --bat --pwsh -a --all"
else else
_installed_packages _installed_packages
fi fi

View file

@ -1442,7 +1442,7 @@ complete -c spack -n '__fish_spack_using_command env activate' -s d -l dir -r -f
complete -c spack -n '__fish_spack_using_command env activate' -s d -l dir -r -d 'activate the environment in this directory' complete -c spack -n '__fish_spack_using_command env activate' -s d -l dir -r -d 'activate the environment in this directory'
# spack env deactivate # spack env deactivate
set -g __fish_spack_optspecs_spack_env_deactivate h/help sh csh fish bat set -g __fish_spack_optspecs_spack_env_deactivate h/help sh csh fish bat pwsh
complete -c spack -n '__fish_spack_using_command env deactivate' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command env deactivate' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command env deactivate' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command env deactivate' -s h -l help -d 'show this help message and exit'
complete -c spack -n '__fish_spack_using_command env deactivate' -l sh -f -a shell complete -c spack -n '__fish_spack_using_command env deactivate' -l sh -f -a shell
@ -1453,6 +1453,8 @@ complete -c spack -n '__fish_spack_using_command env deactivate' -l fish -f -a s
complete -c spack -n '__fish_spack_using_command env deactivate' -l fish -d 'print fish commands to activate the environment' complete -c spack -n '__fish_spack_using_command env deactivate' -l fish -d 'print fish commands to activate the environment'
complete -c spack -n '__fish_spack_using_command env deactivate' -l bat -f -a shell complete -c spack -n '__fish_spack_using_command env deactivate' -l bat -f -a shell
complete -c spack -n '__fish_spack_using_command env deactivate' -l bat -d 'print bat commands to activate the environment' complete -c spack -n '__fish_spack_using_command env deactivate' -l bat -d 'print bat commands to activate the environment'
complete -c spack -n '__fish_spack_using_command env deactivate' -l pwsh -f -a shell
complete -c spack -n '__fish_spack_using_command env deactivate' -l pwsh -d 'print pwsh commands to activate the environment'
# spack env create # spack env create
set -g __fish_spack_optspecs_spack_env_create h/help d/dir keep-relative without-view with-view= set -g __fish_spack_optspecs_spack_env_create h/help d/dir keep-relative without-view with-view=
@ -1972,7 +1974,7 @@ complete -c spack -n '__fish_spack_using_command list' -l update -r -f -a update
complete -c spack -n '__fish_spack_using_command list' -l update -r -d 'write output to the specified file, if any package is newer' complete -c spack -n '__fish_spack_using_command list' -l update -r -d 'write output to the specified file, if any package is newer'
# spack load # spack load
set -g __fish_spack_optspecs_spack_load h/help sh csh fish bat first only= list set -g __fish_spack_optspecs_spack_load h/help sh csh fish bat pwsh first only= list
complete -c spack -n '__fish_spack_using_command_pos_remainder 0 load' -f -a '(__fish_spack_installed_specs)' complete -c spack -n '__fish_spack_using_command_pos_remainder 0 load' -f -a '(__fish_spack_installed_specs)'
complete -c spack -n '__fish_spack_using_command load' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command load' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command load' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command load' -s h -l help -d 'show this help message and exit'
@ -1984,6 +1986,8 @@ complete -c spack -n '__fish_spack_using_command load' -l fish -f -a shell
complete -c spack -n '__fish_spack_using_command load' -l fish -d 'print fish commands to load the package' complete -c spack -n '__fish_spack_using_command load' -l fish -d 'print fish commands to load the package'
complete -c spack -n '__fish_spack_using_command load' -l bat -f -a shell complete -c spack -n '__fish_spack_using_command load' -l bat -f -a shell
complete -c spack -n '__fish_spack_using_command load' -l bat -d 'print bat commands to load the package' complete -c spack -n '__fish_spack_using_command load' -l bat -d 'print bat commands to load the package'
complete -c spack -n '__fish_spack_using_command load' -l pwsh -f -a shell
complete -c spack -n '__fish_spack_using_command load' -l pwsh -d 'print pwsh commands to load the package'
complete -c spack -n '__fish_spack_using_command load' -l first -f -a load_first complete -c spack -n '__fish_spack_using_command load' -l first -f -a load_first
complete -c spack -n '__fish_spack_using_command load' -l first -d 'load the first match if multiple packages match the spec' complete -c spack -n '__fish_spack_using_command load' -l first -d 'load the first match if multiple packages match the spec'
complete -c spack -n '__fish_spack_using_command load' -l only -r -f -a 'package dependencies' complete -c spack -n '__fish_spack_using_command load' -l only -r -f -a 'package dependencies'
@ -2845,7 +2849,7 @@ complete -c spack -n '__fish_spack_using_command unit-test' -l showlocals -f -a
complete -c spack -n '__fish_spack_using_command unit-test' -l showlocals -d 'show local variable values in tracebacks' complete -c spack -n '__fish_spack_using_command unit-test' -l showlocals -d 'show local variable values in tracebacks'
# spack unload # spack unload
set -g __fish_spack_optspecs_spack_unload h/help sh csh fish bat a/all set -g __fish_spack_optspecs_spack_unload h/help sh csh fish bat pwsh a/all
complete -c spack -n '__fish_spack_using_command_pos_remainder 0 unload' -f -a '(__fish_spack_installed_specs)' complete -c spack -n '__fish_spack_using_command_pos_remainder 0 unload' -f -a '(__fish_spack_installed_specs)'
complete -c spack -n '__fish_spack_using_command unload' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command unload' -s h -l help -f -a help
complete -c spack -n '__fish_spack_using_command unload' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command unload' -s h -l help -d 'show this help message and exit'
@ -2857,6 +2861,8 @@ complete -c spack -n '__fish_spack_using_command unload' -l fish -f -a shell
complete -c spack -n '__fish_spack_using_command unload' -l fish -d 'print fish commands to load the package' complete -c spack -n '__fish_spack_using_command unload' -l fish -d 'print fish commands to load the package'
complete -c spack -n '__fish_spack_using_command unload' -l bat -f -a shell complete -c spack -n '__fish_spack_using_command unload' -l bat -f -a shell
complete -c spack -n '__fish_spack_using_command unload' -l bat -d 'print bat commands to load the package' complete -c spack -n '__fish_spack_using_command unload' -l bat -d 'print bat commands to load the package'
complete -c spack -n '__fish_spack_using_command unload' -l pwsh -f -a shell
complete -c spack -n '__fish_spack_using_command unload' -l pwsh -d 'print pwsh commands to load the package'
complete -c spack -n '__fish_spack_using_command unload' -s a -l all -f -a all complete -c spack -n '__fish_spack_using_command unload' -s a -l all -f -a all
complete -c spack -n '__fish_spack_using_command unload' -s a -l all -d 'unload all loaded Spack packages' complete -c spack -n '__fish_spack_using_command unload' -s a -l all -d 'unload all loaded Spack packages'