summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGreg Becker <becker33@llnl.gov>2020-06-26 09:57:22 -0500
committerGitHub <noreply@github.com>2020-06-26 09:57:22 -0500
commitec108dbebdbb00ab517dd8f84dbb976d6078a93a (patch)
tree7850394413ead529aa67742e8388631035c230b9 /lib
parentc401c63156b362fda12f5bf6d8b95a99c2540ad1 (diff)
downloadspack-ec108dbebdbb00ab517dd8f84dbb976d6078a93a.tar.gz
spack-ec108dbebdbb00ab517dd8f84dbb976d6078a93a.tar.bz2
spack-ec108dbebdbb00ab517dd8f84dbb976d6078a93a.tar.xz
spack-ec108dbebdbb00ab517dd8f84dbb976d6078a93a.zip
Allow `spack remove -f` and `spack uninstall` to work on matrices (#17222)
* Allow `spack remove -f` and `spack uninstall` to work on matrices Allow Environment.remove(force=True) to remove the concrete spec from the environment even when the user spec cannot be removed because it is in a matrix.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/environment.py20
-rw-r--r--lib/spack/spack/test/cmd/env.py45
2 files changed, 55 insertions, 10 deletions
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 8eab70b544..5ec683f6b2 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -892,13 +892,23 @@ class Environment(object):
old_specs = set(self.user_specs)
for spec in matches:
if spec in list_to_change:
- list_to_change.remove(spec)
-
- self.update_stale_references(list_name)
+ try:
+ list_to_change.remove(spec)
+ self.update_stale_references(list_name)
+ new_specs = set(self.user_specs)
+ except spack.spec_list.SpecListError:
+ # define new specs list
+ new_specs = set(self.user_specs)
+ msg = "Spec '%s' is part of a spec matrix and " % spec
+ msg += "cannot be removed from list '%s'." % list_to_change
+ if force:
+ msg += " It will be removed from the concrete specs."
+ # Mock new specs so we can remove this spec from
+ # concrete spec lists
+ new_specs.remove(spec)
+ tty.warn(msg)
# If force, update stale concretized specs
- # Only check specs removed by this operation
- new_specs = set(self.user_specs)
for spec in old_specs - new_specs:
if force and spec in self.concretized_user_specs:
i = self.concretized_user_specs.index(spec)
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index 46977d8eec..b1cc9ce8b5 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -19,7 +19,6 @@ from spack.spec import Spec
from spack.main import SpackCommand
from spack.stage import stage_prefix
-from spack.spec_list import SpecListError
from spack.util.mock_package import MockPackageMultiRepo
import spack.util.spack_json as sjson
from spack.util.path import substitute_path_variables
@@ -1234,7 +1233,7 @@ env:
assert Spec('callpath ^mpich') in test.user_specs
-def test_stack_yaml_attempt_remove_from_matrix(tmpdir):
+def test_stack_yaml_remove_from_matrix_no_effect(tmpdir):
filename = str(tmpdir.join('spack.yaml'))
with open(filename, 'w') as f:
f.write("""\
@@ -1249,9 +1248,45 @@ env:
""")
with tmpdir.as_cwd():
env('create', 'test', './spack.yaml')
- with pytest.raises(SpecListError):
- with ev.read('test'):
- remove('-l', 'packages', 'mpileaks')
+ with ev.read('test') as e:
+ before = e.user_specs.specs
+ remove('-l', 'packages', 'mpileaks')
+ after = e.user_specs.specs
+
+ assert before == after
+
+
+def test_stack_yaml_force_remove_from_matrix(tmpdir):
+ filename = str(tmpdir.join('spack.yaml'))
+ with open(filename, 'w') as f:
+ f.write("""\
+env:
+ definitions:
+ - packages:
+ - matrix:
+ - [mpileaks, callpath]
+ - [target=be]
+ specs:
+ - $packages
+""")
+ with tmpdir.as_cwd():
+ env('create', 'test', './spack.yaml')
+ with ev.read('test') as e:
+ concretize()
+
+ before_user = e.user_specs.specs
+ before_conc = e.concretized_user_specs
+
+ remove('-f', '-l', 'packages', 'mpileaks')
+
+ after_user = e.user_specs.specs
+ after_conc = e.concretized_user_specs
+
+ assert before_user == after_user
+
+ mpileaks_spec = Spec('mpileaks target=be')
+ assert mpileaks_spec in before_conc
+ assert mpileaks_spec not in after_conc
def test_stack_concretize_extraneous_deps(tmpdir, config, mock_packages):