summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <me@harmenstoppels.nl>2024-04-16 18:09:32 +0200
committerGitHub <noreply@github.com>2024-04-16 16:09:32 +0000
commit9ff5a305745df7e1209c9fa0c79641b6a15a99ec (patch)
tree9874e39b32f6c5e5178efd2dc530414620f44e3d
parent9a6c0133658ce0905ff1565160faea3fc69ba9b2 (diff)
downloadspack-9ff5a305745df7e1209c9fa0c79641b6a15a99ec.tar.gz
spack-9ff5a305745df7e1209c9fa0c79641b6a15a99ec.tar.bz2
spack-9ff5a305745df7e1209c9fa0c79641b6a15a99ec.tar.xz
spack-9ff5a305745df7e1209c9fa0c79641b6a15a99ec.zip
concretize.lp: fix issue with reuse of conditional variants (#43676)
Currently if you request pkg +example where example is a conditional variant, and you have a pkg in the database for which the condition did not hold (so no +example nor ~example), the solver would reuse it regardless, not imposing +example. The change rules out exactly one thing: variant_set without variant_value, which in practice could only happen when not node_has_variant (i.e. when under the current package.py rules the variant's when condition did not trigger).
-rw-r--r--lib/spack/spack/solver/concretize.lp8
-rw-r--r--lib/spack/spack/test/concretize.py16
2 files changed, 18 insertions, 6 deletions
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 5f8163c61b..5cabd60be3 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -891,12 +891,8 @@ error(100, "{0} variant '{1}' cannot have values '{2}' and '{3}' as they come fr
Set1 < Set2, % see[1]
build(node(ID, Package)).
-% variant_set is an explicitly set variant value. If it's not 'set',
-% we revert to the default value. If it is set, we force the set value
-attr("variant_value", PackageNode, Variant, Value)
- :- attr("node", PackageNode),
- node_has_variant(PackageNode, Variant),
- attr("variant_set", PackageNode, Variant, Value).
+:- attr("variant_set", node(ID, Package), Variant, Value),
+ not attr("variant_value", node(ID, Package), Variant, Value).
% The rules below allow us to prefer default values for variants
% whenever possible. If a variant is set in a spec, or if it is
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index d7df2d6bc8..acc2d0f4e5 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1351,6 +1351,22 @@ class TestConcretize:
assert root.dag_hash() != new_root_without_reuse.dag_hash()
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
+ @pytest.mark.regression("43663")
+ def test_no_reuse_when_variant_condition_does_not_hold(self, mutable_database, mock_packages):
+ spack.config.set("concretizer:reuse", True)
+
+ # Install a spec for which the `version_based` variant condition does not hold
+ old = Spec("conditional-variant-pkg @1").concretized()
+ old.package.do_install(fake=True, explicit=True)
+
+ # Then explicitly require a spec with `+version_based`, which shouldn't reuse previous spec
+ new1 = Spec("conditional-variant-pkg +version_based").concretized()
+ assert new1.satisfies("@2 +version_based")
+
+ new2 = Spec("conditional-variant-pkg +two_whens").concretized()
+ assert new2.satisfies("@2 +two_whens +version_based")
+
+ @pytest.mark.only_clingo("Use case not supported by the original concretizer")
def test_reuse_with_flags(self, mutable_database, mutable_config):
spack.config.set("concretizer:reuse", True)
spec = Spec("a cflags=-g cxxflags=-g").concretized()