summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2023-11-23 11:30:39 +0100
committerGitHub <noreply@github.com>2023-11-23 11:30:39 +0100
commitee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f (patch)
tree652c06204e3ce06dd2641df8feb1e3d26420db60
parentde64ce5541eb4055a26e6ba5d82c37e5797612c0 (diff)
downloadspack-ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f.tar.gz
spack-ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f.tar.bz2
spack-ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f.tar.xz
spack-ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f.zip
ASP-based solver: don't error for type mismatch on preferences (#41138)
This commit discards type mismatches or failures to validate a package preference during concretization. The values discarded are logged as debug level messages. It also adds a config audit to help users spot misconfigurations in packages.yaml preferences.
-rw-r--r--lib/spack/spack/audit.py48
-rw-r--r--lib/spack/spack/solver/asp.py8
-rw-r--r--lib/spack/spack/test/concretize_preferences.py10
3 files changed, 65 insertions, 1 deletions
diff --git a/lib/spack/spack/audit.py b/lib/spack/spack/audit.py
index d0a68cf212..970e4a3b36 100644
--- a/lib/spack/spack/audit.py
+++ b/lib/spack/spack/audit.py
@@ -286,6 +286,54 @@ def _deprecated_preferences(error_cls):
return errors
+@config_packages
+def _avoid_mismatched_variants(error_cls):
+ """Warns if variant preferences have mismatched types or names."""
+ errors = []
+ packages_yaml = spack.config.CONFIG.get_config("packages")
+
+ def make_error(config_data, summary):
+ s = io.StringIO()
+ s.write("Occurring in the following file:\n")
+ syaml.dump_config(config_data, stream=s, blame=True)
+ return error_cls(summary=summary, details=[s.getvalue()])
+
+ for pkg_name in packages_yaml:
+ # 'all:' must be more forgiving, since it is setting defaults for everything
+ if pkg_name == "all" or "variants" not in packages_yaml[pkg_name]:
+ continue
+
+ preferences = packages_yaml[pkg_name]["variants"]
+ if not isinstance(preferences, list):
+ preferences = [preferences]
+
+ for variants in preferences:
+ current_spec = spack.spec.Spec(variants)
+ pkg_cls = spack.repo.PATH.get_pkg_class(pkg_name)
+ for variant in current_spec.variants.values():
+ # Variant does not exist at all
+ if variant.name not in pkg_cls.variants:
+ summary = (
+ f"Setting a preference for the '{pkg_name}' package to the "
+ f"non-existing variant '{variant.name}'"
+ )
+ errors.append(make_error(preferences, summary))
+ continue
+
+ # Variant cannot accept this value
+ s = spack.spec.Spec(pkg_name)
+ try:
+ s.update_variant_validate(variant.name, variant.value)
+ except Exception:
+ summary = (
+ f"Setting the variant '{variant.name}' of the '{pkg_name}' package "
+ f"to the invalid value '{str(variant)}'"
+ )
+ errors.append(make_error(preferences, summary))
+
+ return errors
+
+
#: Sanity checks on package directives
package_directives = AuditClass(
group="packages",
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index e3068e7db4..f723acb0e9 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1831,7 +1831,13 @@ class SpackSolverSetup:
# perform validation of the variant and values
spec = spack.spec.Spec(pkg_name)
- spec.update_variant_validate(variant_name, values)
+ try:
+ spec.update_variant_validate(variant_name, values)
+ except (spack.variant.InvalidVariantValueError, KeyError, ValueError) as e:
+ tty.debug(
+ f"[SETUP]: rejected {str(variant)} as a preference for {pkg_name}: {str(e)}"
+ )
+ continue
for value in values:
self.variant_values_from_specs.add((pkg_name, variant.name, value))
diff --git a/lib/spack/spack/test/concretize_preferences.py b/lib/spack/spack/test/concretize_preferences.py
index d061f9a8f5..929ae0a9ec 100644
--- a/lib/spack/spack/test/concretize_preferences.py
+++ b/lib/spack/spack/test/concretize_preferences.py
@@ -504,3 +504,13 @@ mpich:
with spack.config.override("packages:sticky-variant", {"variants": "+allow-gcc"}):
s = Spec("sticky-variant %gcc").concretized()
assert s.satisfies("%gcc") and s.satisfies("+allow-gcc")
+
+ @pytest.mark.regression("41134")
+ @pytest.mark.only_clingo("Not backporting the fix to the old concretizer")
+ def test_default_preference_variant_different_type_does_not_error(self):
+ """Tests that a different type for an existing variant in the 'all:' section of
+ packages.yaml doesn't fail with an error.
+ """
+ with spack.config.override("packages:all", {"variants": "+foo"}):
+ s = Spec("a").concretized()
+ assert s.satisfies("foo=bar")