From c0c9ab113e0078c53e60df6cb7cb064e6f92c45b Mon Sep 17 00:00:00 2001 From: Harmen Stoppels Date: Mon, 11 Oct 2021 12:56:03 +0200 Subject: 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 ``` --- lib/spack/spack/cmd/env.py | 58 +++++++++++++++++++++++++++++------------ lib/spack/spack/test/cmd/env.py | 12 +++++++++ 2 files changed, 54 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py index ae45e105de..5b9caa0877 100644 --- a/lib/spack/spack/cmd/env.py +++ b/lib/spack/spack/cmd/env.py @@ -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 diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 5c57035527..553d80c562 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -2681,3 +2681,15 @@ spack: 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)) -- cgit v1.2.3-60-g2f50