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
This commit is contained in:
Massimiliano Culpo 2021-08-26 21:20:05 +02:00 committed by GitHub
parent c963bdee8b
commit 29d1bc6546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 23 deletions

View File

@ -23,6 +23,7 @@
import spack.architecture
import spack.binary_distribution
import spack.config
import spack.environment
import spack.main
import spack.paths
import spack.repo
@ -421,6 +422,7 @@ def _bootstrap_config_scopes():
@contextlib.contextmanager
def ensure_bootstrap_configuration():
bootstrap_store_path = store_path()
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):

View File

@ -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')

View File

@ -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()
with spack.bootstrap.ensure_bootstrap_configuration():
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)
_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:

View File

@ -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."""

View File

@ -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