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 shutil
import sys
import tempfile
import llnl.util.filesystem as fs
import llnl.util.tty as tty
@ -69,24 +70,38 @@ def env_activate_setup_parser(subparser):
const=False, default=True,
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(
'-p', '--prompt', action='store_true', default=False,
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')
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):
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:
spack.cmd.common.shell_init_instructions(
"spack env activate",
" eval `spack env activate {sh_arg} %s`" % env,
" eval `spack env activate {sh_arg} [...]`",
)
return 1
@ -95,21 +110,32 @@ def env_activate(args):
tty.die('Calling spack env activate with --env, --env-dir and --no-env '
'is ambiguous')
if ev.exists(env) and not args.dir:
spack_env = ev.root(env)
short_name = env
env_prompt = '[%s]' % env
env_name_or_dir = args.activate_env or args.dir
elif ev.is_env_dir(env):
# Temporary environment
if args.temp:
env = create_temp_env_directory()
spack_env = os.path.abspath(env)
short_name = os.path.basename(os.path.abspath(env))
env_prompt = '[%s]' % short_name
short_name = os.path.basename(spack_env)
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:
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'):
tty.debug("Environment %s is already active" % args.activate_env)
tty.debug("Environment is already active")
return
# Activate new environment

View file

@ -2681,3 +2681,15 @@ def test_custom_store_in_environment(mutable_config, tmpdir):
with spack.environment.Environment(str(tmpdir)):
assert str(spack.store.root) == '/tmp/store'
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`'
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 --help
@ -360,6 +360,12 @@ echo "Testing 'despacktivate'"
despacktivate
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.
#

View file

@ -137,7 +137,7 @@ contains " spack env list " spack env list --help
title 'Testing `spack env activate`'
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 --help
@ -173,3 +173,9 @@ echo "Testing 'despacktivate'"
despacktivate
is_not_set SPACK_ENV
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() {
if $list_options
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
_environments
fi