diff options
author | Harmen Stoppels <me@harmenstoppels.nl> | 2024-04-16 18:09:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-16 16:09:32 +0000 |
commit | 9ff5a305745df7e1209c9fa0c79641b6a15a99ec (patch) | |
tree | 9874e39b32f6c5e5178efd2dc530414620f44e3d | |
parent | 9a6c0133658ce0905ff1565160faea3fc69ba9b2 (diff) | |
download | spack-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.lp | 8 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 16 |
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() |