Add spack env activate --temp (#25388)

Creates an environment in a temporary directory and activates it, which
is useful for a quick ephemeral environment:

```
$ spack env activate -p --temp
[spack-1a203lyg] $ spack add zlib
==> Adding zlib to environment /tmp/spack-1a203lyg
==> Updating view at /tmp/spack-1a203lyg/.spack-env/view
```
This commit is contained in:
Harmen Stoppels 2021-10-11 12:56:03 +02:00 committed by GitHub
parent f28b08bf02
commit c0c9ab113e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 19 deletions

View File

@ -6,6 +6,7 @@
import os import os
import shutil import shutil
import sys import sys
import tempfile
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
import llnl.util.tty as tty import llnl.util.tty as tty
@ -69,24 +70,38 @@ def env_activate_setup_parser(subparser):
const=False, default=True, const=False, default=True,
help="do not update PATH etc. with associated view") help="do not update PATH etc. with associated view")
subparser.add_argument(
'-d', '--dir', action='store_true', default=False,
help="force spack to treat env as a directory, not a name")
subparser.add_argument( subparser.add_argument(
'-p', '--prompt', action='store_true', default=False, '-p', '--prompt', action='store_true', default=False,
help="decorate the command line prompt when activating") help="decorate the command line prompt when activating")
subparser.add_argument(
metavar='env', dest='activate_env', env_options = subparser.add_mutually_exclusive_group()
env_options.add_argument(
'--temp', action='store_true', default=False,
help='create and activate an environment in a temporary directory')
env_options.add_argument(
'-d', '--dir', default=None,
help="activate the environment in this directory")
env_options.add_argument(
metavar='env', dest='activate_env', nargs='?', default=None,
help='name of environment to activate') help='name of environment to activate')
def create_temp_env_directory():
"""
Returns the path of a temporary directory in which to
create an environment
"""
return tempfile.mkdtemp(prefix="spack-")
def env_activate(args): def env_activate(args):
env = args.activate_env if not args.activate_env and not args.dir and not args.temp:
tty.die('spack env activate requires an environment name, directory, or --temp')
if not args.shell: if not args.shell:
spack.cmd.common.shell_init_instructions( spack.cmd.common.shell_init_instructions(
"spack env activate", "spack env activate",
" eval `spack env activate {sh_arg} %s`" % env, " eval `spack env activate {sh_arg} [...]`",
) )
return 1 return 1
@ -95,21 +110,32 @@ def env_activate(args):
tty.die('Calling spack env activate with --env, --env-dir and --no-env ' tty.die('Calling spack env activate with --env, --env-dir and --no-env '
'is ambiguous') 'is ambiguous')
if ev.exists(env) and not args.dir: env_name_or_dir = args.activate_env or args.dir
spack_env = ev.root(env)
short_name = env
env_prompt = '[%s]' % env
elif ev.is_env_dir(env): # Temporary environment
if args.temp:
env = create_temp_env_directory()
spack_env = os.path.abspath(env) spack_env = os.path.abspath(env)
short_name = os.path.basename(os.path.abspath(env)) short_name = os.path.basename(spack_env)
env_prompt = '[%s]' % short_name 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)
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)
else: else:
tty.die("No such environment: '%s'" % env) tty.die("No such environment: '%s'" % env_name_or_dir)
env_prompt = '[%s]' % short_name
if spack_env == os.environ.get('SPACK_ENV'): if spack_env == os.environ.get('SPACK_ENV'):
tty.debug("Environment %s is already active" % args.activate_env) tty.debug("Environment is already active")
return return
# Activate new environment # Activate new environment

View File

@ -2681,3 +2681,15 @@ def test_custom_store_in_environment(mutable_config, tmpdir):
with spack.environment.Environment(str(tmpdir)): with spack.environment.Environment(str(tmpdir)):
assert str(spack.store.root) == '/tmp/store' assert str(spack.store.root) == '/tmp/store'
assert str(spack.store.root) == current_store_root assert str(spack.store.root) == current_store_root
def test_activate_temp(monkeypatch, tmpdir):
"""Tests whether `spack env activate --temp` creates an environment in a
temporary directory"""
env_dir = lambda: str(tmpdir)
monkeypatch.setattr(spack.cmd.env, "create_temp_env_directory", env_dir)
shell = env('activate', '--temp', '--sh')
active_env_var = next(line for line in shell.splitlines()
if ev.spack_env_var in line)
assert str(tmpdir) in active_env_var
assert ev.is_env_dir(str(tmpdir))

View File

@ -333,7 +333,7 @@ spt_contains " spack env list " spack env list --help
title 'Testing `spack env activate`' title 'Testing `spack env activate`'
spt_contains "No such environment:" spack env activate no_such_environment spt_contains "No such environment:" spack env activate no_such_environment
spt_contains "usage: spack env activate " spack env activate spt_contains "env activate requires an environment " spack env activate
spt_contains "usage: spack env activate " spack env activate -h spt_contains "usage: spack env activate " spack env activate -h
spt_contains "usage: spack env activate " spack env activate --help spt_contains "usage: spack env activate " spack env activate --help
@ -360,6 +360,12 @@ echo "Testing 'despacktivate'"
despacktivate despacktivate
is_not_set SPACK_ENV is_not_set SPACK_ENV
echo "Testing 'spack env activate --temp'"
spack env activate --temp
is_set SPACK_ENV
spack env deactivate
is_not_set SPACK_ENV
# #
# NOTE: `--prompt` on fish does nothing => currently not implemented. # NOTE: `--prompt` on fish does nothing => currently not implemented.
# #

View File

@ -137,7 +137,7 @@ contains " spack env list " spack env list --help
title 'Testing `spack env activate`' title 'Testing `spack env activate`'
contains "No such environment:" spack env activate no_such_environment contains "No such environment:" spack env activate no_such_environment
contains "usage: spack env activate " spack env activate contains "env activate requires an environment " spack env activate
contains "usage: spack env activate " spack env activate -h contains "usage: spack env activate " spack env activate -h
contains "usage: spack env activate " spack env activate --help contains "usage: spack env activate " spack env activate --help
@ -173,3 +173,9 @@ echo "Testing 'despacktivate'"
despacktivate despacktivate
is_not_set SPACK_ENV is_not_set SPACK_ENV
is_not_set SPACK_OLD_PS1 is_not_set SPACK_OLD_PS1
echo "Testing 'spack env activate --temp'"
spack env activate --temp
is_set SPACK_ENV
spack env deactivate
is_not_set SPACK_ENV

View File

@ -911,7 +911,7 @@ _spack_env() {
_spack_env_activate() { _spack_env_activate() {
if $list_options if $list_options
then then
SPACK_COMPREPLY="-h --help --sh --csh --fish -v --with-view -V --without-view -d --dir -p --prompt" SPACK_COMPREPLY="-h --help --sh --csh --fish -v --with-view -V --without-view -p --prompt --temp -d --dir"
else else
_environments _environments
fi fi