spack env activate: create & activate default environment without args (#40756)
This PR implements the concept of "default environment", which doesn't have to be created explicitly. The aim is to lower the barrier for adopting environments. To (create and) activate the default environment, run ``` $ spack env activate ``` This mimics the behavior of ``` $ cd ``` which brings you to your home directory. This is not a breaking change, since `spack env activate` without arguments currently errors. It is similar to the already existing `spack env activate --temp` command which always creates an env in a temporary directory, the difference is that the default environment is a managed / named environment named `default`. The name `default` is not a reserved name, it's just that `spack env activate` creates it for you if you don't have it already. With this change, you can get started with environments faster: ``` $ spack env activate [--prompt] $ spack install --add x y z ``` instead of ``` $ spack env create default ==> Created environment 'default in /Users/harmenstoppels/spack/var/spack/environments/default ==> You can activate this environment with: ==> spack env activate default $ spack env activate [--prompt] default $ spack install --add x y z ``` Notice that Spack supports switching (but not stacking) environments, so the parallel with `cd` is pretty clear: ``` $ spack env activate named_env $ spack env status ==> In environment named_env $ spack env activate $ spack env status ==> In environment default ```
This commit is contained in:
parent
141c7de5d8
commit
3c641c8509
5 changed files with 51 additions and 8 deletions
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -144,10 +145,13 @@ def create_temp_env_directory():
|
||||||
return tempfile.mkdtemp(prefix="spack-")
|
return tempfile.mkdtemp(prefix="spack-")
|
||||||
|
|
||||||
|
|
||||||
def env_activate(args):
|
def _tty_info(msg):
|
||||||
if not args.activate_env and not args.dir and not args.temp:
|
"""tty.info like function that prints the equivalent printf statement for eval."""
|
||||||
tty.die("spack env activate requires an environment name, directory, or --temp")
|
decorated = f'{colorize("@*b{==>}")} {msg}\n'
|
||||||
|
print(f"printf {shlex.quote(decorated)};")
|
||||||
|
|
||||||
|
|
||||||
|
def env_activate(args):
|
||||||
if not args.shell:
|
if not args.shell:
|
||||||
spack.cmd.common.shell_init_instructions(
|
spack.cmd.common.shell_init_instructions(
|
||||||
"spack env activate", " eval `spack env activate {sh_arg} [...]`"
|
"spack env activate", " eval `spack env activate {sh_arg} [...]`"
|
||||||
|
@ -160,12 +164,25 @@ def env_activate(args):
|
||||||
|
|
||||||
env_name_or_dir = args.activate_env or args.dir
|
env_name_or_dir = args.activate_env or args.dir
|
||||||
|
|
||||||
|
# When executing `spack env activate` without further arguments, activate
|
||||||
|
# the default environment. It's created when it doesn't exist yet.
|
||||||
|
if not env_name_or_dir and not args.temp:
|
||||||
|
short_name = "default"
|
||||||
|
if not ev.exists(short_name):
|
||||||
|
ev.create(short_name)
|
||||||
|
action = "Created and activated"
|
||||||
|
else:
|
||||||
|
action = "Activated"
|
||||||
|
env_path = ev.root(short_name)
|
||||||
|
_tty_info(f"{action} default environment in {env_path}")
|
||||||
|
|
||||||
# Temporary environment
|
# Temporary environment
|
||||||
if args.temp:
|
elif args.temp:
|
||||||
env = create_temp_env_directory()
|
env = create_temp_env_directory()
|
||||||
env_path = os.path.abspath(env)
|
env_path = os.path.abspath(env)
|
||||||
short_name = os.path.basename(env_path)
|
short_name = os.path.basename(env_path)
|
||||||
ev.create_in_dir(env).write(regenerate=False)
|
ev.create_in_dir(env).write(regenerate=False)
|
||||||
|
_tty_info(f"Created and activated temporary environment in {env_path}")
|
||||||
|
|
||||||
# Managed environment
|
# Managed environment
|
||||||
elif ev.exists(env_name_or_dir) and not args.dir:
|
elif ev.exists(env_name_or_dir) and not args.dir:
|
||||||
|
|
|
@ -2924,6 +2924,25 @@ def test_activate_temp(monkeypatch, tmpdir):
|
||||||
assert ev.is_env_dir(str(tmpdir))
|
assert ev.is_env_dir(str(tmpdir))
|
||||||
|
|
||||||
|
|
||||||
|
def test_activate_default(monkeypatch):
|
||||||
|
"""Tests whether `spack env activate` creates / activates the default
|
||||||
|
environment"""
|
||||||
|
assert not ev.exists("default")
|
||||||
|
|
||||||
|
# Activating it the first time should create it
|
||||||
|
env("activate", "--sh")
|
||||||
|
env("deactivate", "--sh")
|
||||||
|
assert ev.exists("default")
|
||||||
|
|
||||||
|
# Activating it while it already exists should work
|
||||||
|
env("activate", "--sh")
|
||||||
|
env("deactivate", "--sh")
|
||||||
|
assert ev.exists("default")
|
||||||
|
|
||||||
|
env("remove", "-y", "default")
|
||||||
|
assert not ev.exists("default")
|
||||||
|
|
||||||
|
|
||||||
def test_env_view_fail_if_symlink_points_elsewhere(tmpdir, install_mockery, mock_fetch):
|
def test_env_view_fail_if_symlink_points_elsewhere(tmpdir, install_mockery, mock_fetch):
|
||||||
view = str(tmpdir.join("view"))
|
view = str(tmpdir.join("view"))
|
||||||
# Put a symlink to an actual directory in view
|
# Put a symlink to an actual directory in view
|
||||||
|
|
|
@ -371,7 +371,6 @@ 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 "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
|
||||||
|
|
||||||
|
@ -415,6 +414,11 @@ spt_contains 'spack_test_2_env' 'fish' '-c' 'echo $PATH'
|
||||||
spt_does_not_contain 'spack_test_env' 'fish' '-c' 'echo $PATH'
|
spt_does_not_contain 'spack_test_env' 'fish' '-c' 'echo $PATH'
|
||||||
despacktivate
|
despacktivate
|
||||||
|
|
||||||
|
echo "Testing default environment"
|
||||||
|
spack env activate
|
||||||
|
contains "In environment default" spack env status
|
||||||
|
despacktivate
|
||||||
|
|
||||||
echo "Correct error exit codes for activate and deactivate"
|
echo "Correct error exit codes for activate and deactivate"
|
||||||
spt_fails spack env activate nonexisiting_environment
|
spt_fails spack env activate nonexisiting_environment
|
||||||
spt_fails spack env deactivate
|
spt_fails spack env deactivate
|
||||||
|
|
|
@ -140,7 +140,6 @@ 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 "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
|
||||||
|
|
||||||
|
@ -197,6 +196,11 @@ contains "spack_test_2_env" sh -c 'echo $PATH'
|
||||||
does_not_contain "spack_test_env" sh -c 'echo $PATH'
|
does_not_contain "spack_test_env" sh -c 'echo $PATH'
|
||||||
despacktivate
|
despacktivate
|
||||||
|
|
||||||
|
echo "Testing default environment"
|
||||||
|
spack env activate
|
||||||
|
contains "In environment default" spack env status
|
||||||
|
despacktivate
|
||||||
|
|
||||||
echo "Correct error exit codes for activate and deactivate"
|
echo "Correct error exit codes for activate and deactivate"
|
||||||
fails spack env activate nonexisiting_environment
|
fails spack env activate nonexisiting_environment
|
||||||
fails spack env deactivate
|
fails spack env deactivate
|
||||||
|
|
|
@ -126,8 +126,7 @@ _spack_shell_wrapper() {
|
||||||
# Space needed here to differentiate between `-h`
|
# Space needed here to differentiate between `-h`
|
||||||
# argument and environments with "-h" in the name.
|
# argument and environments with "-h" in the name.
|
||||||
# Also see: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
|
# Also see: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
|
||||||
if [ -z ${1+x} ] || \
|
if [ "${_a#* --sh}" != "$_a" ] || \
|
||||||
[ "${_a#* --sh}" != "$_a" ] || \
|
|
||||||
[ "${_a#* --csh}" != "$_a" ] || \
|
[ "${_a#* --csh}" != "$_a" ] || \
|
||||||
[ "${_a#* -h}" != "$_a" ] || \
|
[ "${_a#* -h}" != "$_a" ] || \
|
||||||
[ "${_a#* --help}" != "$_a" ];
|
[ "${_a#* --help}" != "$_a" ];
|
||||||
|
|
Loading…
Reference in a new issue