Deactivate previous env before activating new one (#25409)
* Deactivate previous env before activating new one Currently on develop you can run `spack env activate` multiple times to switch between environments, but they leave traces, even though Spack only supports one active environment at a time. Currently: ```console $ spack env create a $ spack env create b $ spack env activate -p a [a] $ spack env activate -p b [b] [a] $ spack env activate -p b [a] [b] [a] $ spack env activate -p a [a] [b] [c] $ echo $MANPATH | tr ":" "\n" /path/to/environments/a/.spack-env/view/share/man /path/to/environments/a/.spack-env/view/man /path/to/environments/b/.spack-env/view/share/man /path/to/environments/b/.spack-env/view/man ``` This PR fixes that: ```console $ spack env activate -p a [a] $ spack env activate -p b [b] $ spack env activate -p a [a] $ echo $MANPATH | tr ":" "\n" /path/to/environments/a/.spack-env/view/share/man /path/to/environments/a/.spack-env/view/man ```
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
import spack.environment.shell
|
||||
import spack.schema.env
|
||||
import spack.util.string as string
|
||||
from spack.util.environment import EnvironmentModifications
|
||||
|
||||
description = "manage virtual environments"
|
||||
section = "environments"
|
||||
@@ -115,42 +116,45 @@ def env_activate(args):
|
||||
# Temporary environment
|
||||
if args.temp:
|
||||
env = create_temp_env_directory()
|
||||
spack_env = os.path.abspath(env)
|
||||
short_name = os.path.basename(spack_env)
|
||||
env_path = os.path.abspath(env)
|
||||
short_name = os.path.basename(env_path)
|
||||
ev.Environment(env).write(regenerate=False)
|
||||
|
||||
# Named environment
|
||||
elif ev.exists(env_name_or_dir) and not args.dir:
|
||||
spack_env = ev.root(env_name_or_dir)
|
||||
env_path = ev.root(env_name_or_dir)
|
||||
short_name = env_name_or_dir
|
||||
|
||||
# Environment directory
|
||||
elif ev.is_env_dir(env_name_or_dir):
|
||||
spack_env = os.path.abspath(env_name_or_dir)
|
||||
short_name = os.path.basename(spack_env)
|
||||
env_path = os.path.abspath(env_name_or_dir)
|
||||
short_name = os.path.basename(env_path)
|
||||
|
||||
else:
|
||||
tty.die("No such environment: '%s'" % env_name_or_dir)
|
||||
|
||||
env_prompt = '[%s]' % short_name
|
||||
|
||||
if spack_env == os.environ.get('SPACK_ENV'):
|
||||
tty.debug("Environment is already active")
|
||||
return
|
||||
# We only support one active environment at a time, so deactivate the current one.
|
||||
if ev.active_environment() is None:
|
||||
cmds = ''
|
||||
env_mods = EnvironmentModifications()
|
||||
else:
|
||||
cmds = spack.environment.shell.deactivate_header(shell=args.shell)
|
||||
env_mods = spack.environment.shell.deactivate()
|
||||
|
||||
# Activate new environment
|
||||
active_env = ev.Environment(spack_env)
|
||||
cmds = spack.environment.shell.activate_header(
|
||||
active_env = ev.Environment(env_path)
|
||||
cmds += spack.environment.shell.activate_header(
|
||||
env=active_env,
|
||||
shell=args.shell,
|
||||
prompt=env_prompt if args.prompt else None
|
||||
)
|
||||
env_mods = spack.environment.shell.activate(
|
||||
env_mods.extend(spack.environment.shell.activate(
|
||||
env=active_env,
|
||||
add_view=args.with_view
|
||||
)
|
||||
))
|
||||
cmds += env_mods.shell_modifications(args.shell)
|
||||
|
||||
sys.stdout.write(cmds)
|
||||
|
||||
|
||||
@@ -184,7 +188,7 @@ def env_deactivate(args):
|
||||
tty.die('Calling spack env deactivate with --env, --env-dir and --no-env '
|
||||
'is ambiguous')
|
||||
|
||||
if 'SPACK_ENV' not in os.environ:
|
||||
if ev.active_environment() is None:
|
||||
tty.die('No environment is currently active.')
|
||||
|
||||
cmds = spack.environment.shell.deactivate_header(args.shell)
|
||||
|
@@ -134,7 +134,11 @@ def activate(env, use_env_repo=False, add_view=True):
|
||||
|
||||
def deactivate():
|
||||
"""
|
||||
Deactivate an environment and collect corresponding environment modifications
|
||||
Deactivate an environment and collect corresponding environment modifications.
|
||||
|
||||
Note: unloads the environment in its current state, not in the state it was
|
||||
loaded in, meaning that specs that were removed from the spack environment
|
||||
after activation are not unloaded.
|
||||
|
||||
Returns:
|
||||
spack.util.environment.EnvironmentModifications: Environment variables
|
||||
|
Reference in New Issue
Block a user