From 033599c4cd0889af2cb8ae4b52984fa88558f5c2 Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Wed, 24 May 2023 15:41:57 +0200 Subject: bugfix: env concretize after remove (#37877) --- lib/spack/spack/environment/environment.py | 14 ++++++++++++++ lib/spack/spack/test/cmd/env.py | 13 +++++++++++++ 2 files changed, 27 insertions(+) (limited to 'lib') diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py index 3d56a7d207..d2a025443b 100644 --- a/lib/spack/spack/environment/environment.py +++ b/lib/spack/spack/environment/environment.py @@ -1351,6 +1351,10 @@ class Environment: self.concretized_order = [] self.specs_by_hash = {} + # Remove concrete specs that no longer correlate to a user spec + for spec in set(self.concretized_user_specs) - set(self.user_specs): + self.deconcretize(spec) + # Pick the right concretization strategy if self.unify == "when_possible": return self._concretize_together_where_possible(tests=tests) @@ -1364,6 +1368,16 @@ class Environment: msg = "concretization strategy not implemented [{0}]" raise SpackEnvironmentError(msg.format(self.unify)) + def deconcretize(self, spec): + # spec has to be a root of the environment + index = self.concretized_user_specs.index(spec) + dag_hash = self.concretized_order.pop(index) + del self.concretized_user_specs[index] + + # If this was the only user spec that concretized to this concrete spec, remove it + if dag_hash not in self.concretized_order: + del self.specs_by_hash[dag_hash] + def _get_specs_to_concretize( self, ) -> Tuple[Set[spack.spec.Spec], Set[spack.spec.Spec], List[spack.spec.Spec]]: diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 5855e0e208..f89b708568 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -390,6 +390,19 @@ def test_remove_after_concretize(): assert not any(s.name == "mpileaks" for s in env_specs) +def test_remove_before_concretize(): + e = ev.create("test") + e.unify = True + + e.add("mpileaks") + e.concretize() + + e.remove("mpileaks") + e.concretize() + + assert not list(e.concretized_specs()) + + def test_remove_command(): env("create", "test") assert "test" in env("list") -- cgit v1.2.3-70-g09d2