summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-08-26 21:20:05 +0200
committerGitHub <noreply@github.com>2021-08-26 12:20:05 -0700
commit29d1bc6546def4bcd09c0a5b533de9f39a78d910 (patch)
tree576e6359be1c861e5cffbba9b6d3faf439a7de73 /lib
parentc963bdee8b8507c3eb50072ccfee275e52c778b6 (diff)
downloadspack-29d1bc6546def4bcd09c0a5b533de9f39a78d910.tar.gz
spack-29d1bc6546def4bcd09c0a5b533de9f39a78d910.tar.bz2
spack-29d1bc6546def4bcd09c0a5b533de9f39a78d910.tar.xz
spack-29d1bc6546def4bcd09c0a5b533de9f39a78d910.zip
Ensure environment are deactivated when bootstrapping (#25607)
Fixes #25603 This commit adds a new context manager to temporarily deactivate active environments. This context manager is used when setting up bootstrapping configuration to make sure that the current environment is not affected by operations on the bootstrap store. * Preserve exit code 1 if nothing is found * Use context manager for the environment
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/bootstrap.py20
-rw-r--r--lib/spack/spack/cmd/clean.py2
-rw-r--r--lib/spack/spack/cmd/find.py26
-rw-r--r--lib/spack/spack/environment.py12
-rw-r--r--lib/spack/spack/test/bootstrap.py15
5 files changed, 52 insertions, 23 deletions
diff --git a/lib/spack/spack/bootstrap.py b/lib/spack/spack/bootstrap.py
index 09d9c6e3a8..be48d66a21 100644
--- a/lib/spack/spack/bootstrap.py
+++ b/lib/spack/spack/bootstrap.py
@@ -23,6 +23,7 @@ import llnl.util.tty as tty
import spack.architecture
import spack.binary_distribution
import spack.config
+import spack.environment
import spack.main
import spack.paths
import spack.repo
@@ -421,15 +422,16 @@ def _bootstrap_config_scopes():
@contextlib.contextmanager
def ensure_bootstrap_configuration():
bootstrap_store_path = store_path()
- with spack.architecture.use_platform(spack.architecture.real_platform()):
- with spack.repo.use_repositories(spack.paths.packages_path):
- with spack.store.use_store(bootstrap_store_path):
- # Default configuration scopes excluding command line
- # and builtin but accounting for platform specific scopes
- config_scopes = _bootstrap_config_scopes()
- with spack.config.use_configuration(*config_scopes):
- with spack_python_interpreter():
- yield
+ with spack.environment.deactivate_environment():
+ with spack.architecture.use_platform(spack.architecture.real_platform()):
+ with spack.repo.use_repositories(spack.paths.packages_path):
+ with spack.store.use_store(bootstrap_store_path):
+ # Default configuration scopes excluding command line
+ # and builtin but accounting for platform specific scopes
+ config_scopes = _bootstrap_config_scopes()
+ with spack.config.use_configuration(*config_scopes):
+ with spack_python_interpreter():
+ yield
def store_path():
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index 3b66358293..ebcf7cc862 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -104,6 +104,6 @@ def clean(parser, args):
if args.bootstrap:
msg = 'Removing software in "{0}"'
tty.msg(msg.format(spack.bootstrap.store_path()))
- with spack.store.use_store(spack.bootstrap.store_path()):
+ with spack.bootstrap.ensure_bootstrap_configuration():
uninstall = spack.main.SpackCommand('uninstall')
uninstall('-a', '-y')
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 13066578e3..8378f6ef6e 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -205,24 +205,24 @@ def display_env(env, args, decorator):
def find(parser, args):
- q_args = query_arguments(args)
- # Query the current store or the internal bootstrap store if required
if args.bootstrap:
bootstrap_store_path = spack.bootstrap.store_path()
- msg = 'Showing internal bootstrap store at "{0}"'
- tty.msg(msg.format(bootstrap_store_path))
- with spack.store.use_store(bootstrap_store_path):
- results = args.specs(**q_args)
- else:
- results = args.specs(**q_args)
+ with spack.bootstrap.ensure_bootstrap_configuration():
+ msg = 'Showing internal bootstrap store at "{0}"'
+ tty.msg(msg.format(bootstrap_store_path))
+ _find(parser, args)
+ return
+ _find(parser, args)
- decorator = lambda s, f: f
- added = set()
- removed = set()
+
+def _find(parser, args):
+ q_args = query_arguments(args)
+ results = args.specs(**q_args)
env = ev.active_environment()
+ decorator = lambda s, f: f
if env:
- decorator, added, roots, removed = setup_env(env)
+ decorator, _, roots, _ = setup_env(env)
# use groups by default except with format.
if args.groups is None:
@@ -233,7 +233,7 @@ def find(parser, args):
msg = "No package matches the query: {0}"
msg = msg.format(' '.join(args.constraint))
tty.msg(msg)
- return 1
+ raise SystemExit(1)
# If tags have been specified on the command line, filter by tags
if args.tags:
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 23644dabd9..aa27e5361c 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import collections
+import contextlib
import copy
import os
import re
@@ -2144,6 +2145,17 @@ def is_latest_format(manifest):
return not changed
+@contextlib.contextmanager
+def deactivate_environment():
+ """Deactivate an active environment for the duration of the context."""
+ global _active_environment
+ current, _active_environment = _active_environment, None
+ try:
+ yield
+ finally:
+ _active_environment = current
+
+
class SpackEnvironmentError(spack.error.SpackError):
"""Superclass for all errors to do with Spack environments."""
diff --git a/lib/spack/spack/test/bootstrap.py b/lib/spack/spack/test/bootstrap.py
index fccf67e569..fa5621e373 100644
--- a/lib/spack/spack/test/bootstrap.py
+++ b/lib/spack/spack/test/bootstrap.py
@@ -5,10 +5,17 @@
import pytest
import spack.bootstrap
+import spack.environment
import spack.store
import spack.util.path
+@pytest.fixture
+def active_mock_environment(mutable_config, mutable_mock_env_path):
+ with spack.environment.create('bootstrap-test') as env:
+ yield env
+
+
@pytest.mark.regression('22294')
def test_store_is_restored_correctly_after_bootstrap(mutable_config, tmpdir):
# Prepare a custom store path. This should be in a writeable location
@@ -49,3 +56,11 @@ def test_raising_exception_if_bootstrap_disabled(mutable_config):
# Check the correct exception is raised
with pytest.raises(RuntimeError, match='bootstrapping is currently disabled'):
spack.bootstrap.store_path()
+
+
+@pytest.mark.regression('25603')
+def test_bootstrap_deactivates_environments(active_mock_environment):
+ assert spack.environment.active_environment() == active_mock_environment
+ with spack.bootstrap.ensure_bootstrap_configuration():
+ assert spack.environment.active_environment() is None
+ assert spack.environment.active_environment() == active_mock_environment