From 6a9df34abd35dc5c4292eac1da2d902a4b7f7702 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Thu, 28 Apr 2022 19:40:28 +0200 Subject: [PATCH] ASP-based solver: discard unknown packages from reuse (#30357) * ASP-based solver: discard unknown packages from reuse This is an add-on to #28259 that cover for the case of a single package.py being removed from a repository, rather than an entire custom repository being removed. * Add unit test --- lib/spack/spack/solver/asp.py | 8 +++++--- lib/spack/spack/test/concretize.py | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 6ec041e89b..d3a29fe250 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1661,8 +1661,8 @@ def _facts_from_concrete_spec(self, spec, possible): if spec.name in possible and h not in self.seen_hashes: try: # Only consider installed packages for repo we know - spack.repo.path.repo_for_pkg(spec) - except spack.repo.UnknownNamespaceError: + spack.repo.path.get(spec) + except (spack.repo.UnknownNamespaceError, spack.repo.UnknownPackageError): return # this indicates that there is a spec like this installed @@ -2053,6 +2053,8 @@ def build_specs(self, function_tuples): # namespace assignment is done after the fact, as it is not # currently part of the solve for spec in self._specs.values(): + if spec.namespace: + continue repo = spack.repo.path.repo_for_pkg(spec) spec.namespace = repo.namespace @@ -2062,7 +2064,7 @@ def build_specs(self, function_tuples): # inject patches -- note that we' can't use set() to unique the # roots here, because the specs aren't complete, and the hash # function will loop forever. - roots = [spec.root for spec in self._specs.values()] + roots = [spec.root for spec in self._specs.values() if not spec.root.installed] roots = dict((id(r), r) for r in roots) for root in roots.values(): spack.spec.Spec.inject_patches_variant(root) diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 984f3e9b01..4b573bbeda 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os +import shutil import sys import jinja2 @@ -1645,3 +1646,22 @@ def test_reuse_with_unknown_namespace_dont_raise( with spack.config.override("concretizer:reuse", True): s = Spec('c').concretized() assert s.namespace == 'builtin.mock' + + @pytest.mark.regression('28259') + def test_reuse_with_unknown_package_dont_raise( + self, additional_repo_with_c, mutable_mock_repo, monkeypatch + ): + s = Spec('c').concretized() + assert s.namespace == 'myrepo' + s.package.do_install(fake=True, explicit=True) + + # Here we delete the package.py instead of removing the repo and we + # make it such that "c" doesn't exist in myrepo + del sys.modules['spack.pkg.myrepo.c'] + c_dir = os.path.join(additional_repo_with_c.root, 'packages', 'c') + shutil.rmtree(c_dir) + monkeypatch.setattr(additional_repo_with_c, 'exists', lambda x: False) + + with spack.config.override("concretizer:reuse", True): + s = Spec('c').concretized() + assert s.namespace == 'builtin.mock'