summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-02-23 04:09:43 +0100
committerMassimiliano Culpo <massimiliano.culpo@gmail.com>2021-05-21 15:09:08 +0200
commit8d131934345abc5f0ee61da45a74fa09c07195bb (patch)
tree573edb80735526f27508ed526619d79387572158
parent94bb37c1070c1f032d805e0b7f7622cf736ada14 (diff)
downloadspack-8d131934345abc5f0ee61da45a74fa09c07195bb.tar.gz
spack-8d131934345abc5f0ee61da45a74fa09c07195bb.tar.bz2
spack-8d131934345abc5f0ee61da45a74fa09c07195bb.tar.xz
spack-8d131934345abc5f0ee61da45a74fa09c07195bb.zip
Improve error message for inconsistencies in package.py (#21811)
* Improve error message for inconsistencies in package.py Sometimes directives refer to variants that do not exist. Make it such that: 1. The name of the variant 2. The name of the package which is supposed to have such variant 3. The name of the package making this assumption are all printed in the error message for easier debugging. * Add unit tests (cherry picked from commit 7226bd64dc3b46a1ed361f1e9d7fb4a2a5b65200)
-rw-r--r--lib/spack/spack/solver/asp.py33
-rw-r--r--lib/spack/spack/test/concretize.py12
-rw-r--r--var/spack/repos/builtin.mock/packages/wrong-variant-in-conflicts/package.py13
-rw-r--r--var/spack/repos/builtin.mock/packages/wrong-variant-in-depends-on/package.py13
4 files changed, 66 insertions, 5 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index e36b5a3d3c..789a207d1e 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -647,11 +647,15 @@ class SpackSolverSetup(object):
self.gen.fact(cond_fn(condition_id, pkg_name, dep_spec.name))
# conditions that trigger the condition
- conditions = self.spec_clauses(named_cond, body=True)
+ conditions = self.checked_spec_clauses(
+ named_cond, body=True, required_from=pkg_name
+ )
for pred in conditions:
self.gen.fact(require_fn(condition_id, pred.name, *pred.args))
- imposed_constraints = self.spec_clauses(dep_spec)
+ imposed_constraints = self.checked_spec_clauses(
+ dep_spec, required_from=pkg_name
+ )
for pred in imposed_constraints:
# imposed "node"-like conditions are no-ops
if pred.name in ("node", "virtual_node"):
@@ -857,6 +861,20 @@ class SpackSolverSetup(object):
self.gen.fact(fn.compiler_version_flag(
compiler.name, compiler.version, name, flag))
+ def checked_spec_clauses(self, *args, **kwargs):
+ """Wrap a call to spec clauses into a try/except block that raise
+ a comprehensible error message in case of failure.
+ """
+ requestor = kwargs.pop('required_from', None)
+ try:
+ clauses = self.spec_clauses(*args, **kwargs)
+ except RuntimeError as exc:
+ msg = str(exc)
+ if requestor:
+ msg += ' [required from package "{0}"]'.format(requestor)
+ raise RuntimeError(msg)
+ return clauses
+
def spec_clauses(self, spec, body=False, transitive=True):
"""Return a list of clauses for a spec mandates are true.
@@ -925,9 +943,14 @@ class SpackSolverSetup(object):
# validate variant value
reserved_names = spack.directives.reserved_names
- if (not spec.virtual and vname not in reserved_names):
- variant_def = spec.package.variants[vname]
- variant_def.validate_or_raise(variant, spec.package)
+ if not spec.virtual and vname not in reserved_names:
+ try:
+ variant_def = spec.package.variants[vname]
+ except KeyError:
+ msg = 'variant "{0}" not found in package "{1}"'
+ raise RuntimeError(msg.format(vname, spec.name))
+ else:
+ variant_def.validate_or_raise(variant, spec.package)
clauses.append(f.variant_value(spec.name, vname, value))
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index dae162a12f..a54a65970f 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1097,3 +1097,15 @@ class TestConcretize(object):
# dependency type declared to infer that the dependency holds.
s = Spec('test-dep-with-imposed-conditions').concretized()
assert 'c' not in s
+
+ @pytest.mark.parametrize('spec_str', [
+ 'wrong-variant-in-conflicts',
+ 'wrong-variant-in-depends-on'
+ ])
+ def test_error_message_for_inconsistent_variants(self, spec_str):
+ if spack.config.get('config:concretizer') == 'original':
+ pytest.xfail('Known failure of the original concretizer')
+
+ s = Spec(spec_str)
+ with pytest.raises(RuntimeError, match='not found in package'):
+ s.concretize()
diff --git a/var/spack/repos/builtin.mock/packages/wrong-variant-in-conflicts/package.py b/var/spack/repos/builtin.mock/packages/wrong-variant-in-conflicts/package.py
new file mode 100644
index 0000000000..7a53904f60
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/wrong-variant-in-conflicts/package.py
@@ -0,0 +1,13 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class WrongVariantInConflicts(Package):
+ """This package has a wrong variant spelled in a conflict."""
+
+ homepage = "http://www.example.com"
+ url = "http://www.example.com/b-1.0.tar.gz"
+
+ version('1.0', '0123456789abcdef0123456789abcdef')
+
+ conflicts('+foo', when='@1.0')
diff --git a/var/spack/repos/builtin.mock/packages/wrong-variant-in-depends-on/package.py b/var/spack/repos/builtin.mock/packages/wrong-variant-in-depends-on/package.py
new file mode 100644
index 0000000000..628a761c7c
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/wrong-variant-in-depends-on/package.py
@@ -0,0 +1,13 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class WrongVariantInDependsOn(Package):
+ """This package has a wrong variant spelled in a depends_on."""
+
+ homepage = "http://www.example.com"
+ url = "http://www.example.com/b-1.0.tar.gz"
+
+ version('1.0', '0123456789abcdef0123456789abcdef')
+
+ depends_on('b+doesnotexist')