summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2024-04-18 17:27:12 +0200
committerGitHub <noreply@github.com>2024-04-18 17:27:12 +0200
commit7cad6c62a37128f7324597b8e414a350b9312f0b (patch)
treeca3bb69718c8500b30fd1f90a3207062bc2082f0 /lib
parenteb2ddf6fa21b774c20791eed80676795b8034d07 (diff)
downloadspack-7cad6c62a37128f7324597b8e414a350b9312f0b.tar.gz
spack-7cad6c62a37128f7324597b8e414a350b9312f0b.tar.bz2
spack-7cad6c62a37128f7324597b8e414a350b9312f0b.tar.xz
spack-7cad6c62a37128f7324597b8e414a350b9312f0b.zip
Associate condition sets from cli to root node (#43710)
This PR prevents a condition_set from having nodes that are not associated with the corresponding root node through some (transitive) dependencies.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/solver/concretize.lp22
-rw-r--r--lib/spack/spack/test/concretize.py23
2 files changed, 42 insertions, 3 deletions
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 5cabd60be3..022c6abe78 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -127,10 +127,12 @@ trigger_node(TriggerID, Node, Node) :-
trigger_condition_holds(TriggerID, Node),
literal(TriggerID).
-% Since we trigger the existence of literal nodes from a condition, we need to construct
-% the condition_set/2 manually below
+% Since we trigger the existence of literal nodes from a condition, we need to construct the condition_set/2
mentioned_in_literal(Root, Mentioned) :- mentioned_in_literal(TriggerID, Root, Mentioned), solve_literal(TriggerID).
-condition_set(node(min_dupe_id, Root), node(min_dupe_id, Mentioned)) :- mentioned_in_literal(Root, Mentioned).
+condition_set(node(min_dupe_id, Root), node(min_dupe_id, Root)) :- mentioned_in_literal(Root, Root).
+
+1 { condition_set(node(min_dupe_id, Root), node(0..Y-1, Mentioned)) : max_dupes(Mentioned, Y) } 1 :-
+ mentioned_in_literal(Root, Mentioned), Mentioned != Root.
% Discriminate between "roots" that have been explicitly requested, and roots that are deduced from "virtual roots"
explicitly_requested_root(node(min_dupe_id, Package)) :-
@@ -138,6 +140,20 @@ explicitly_requested_root(node(min_dupe_id, Package)) :-
trigger_and_effect(Package, TriggerID, EffectID),
imposed_constraint(EffectID, "root", Package).
+
+% Keep track of which nodes are associated with which root DAG
+associated_with_root(RootNode, RootNode) :- attr("root", RootNode).
+
+associated_with_root(RootNode, ChildNode) :-
+ depends_on(ParentNode, ChildNode),
+ associated_with_root(RootNode, ParentNode).
+
+% We cannot have a node in the root condition set, that is not associated with that root
+:- attr("root", RootNode),
+ condition_set(RootNode, node(X, Package)),
+ not virtual(Package),
+ not associated_with_root(RootNode, node(X, Package)).
+
#defined concretize_everything/0.
#defined literal/1.
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index acc2d0f4e5..f897230088 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -2536,6 +2536,29 @@ class TestConcretizeSeparately:
assert len(edges) == 1
assert edges[0].spec.satisfies("@=60")
+ @pytest.mark.regression("43647")
+ def test_specifying_different_versions_build_deps(self):
+ """Tests that we can concretize a spec with nodes using the same build
+ dependency pinned at different versions, when the constraint is specified
+ in the root spec.
+
+ o hdf5@1.0
+ |\
+ o | pinned-gmake@1.0
+ o | gmake@3.0
+ /
+ o gmake@4.1
+
+ """
+ hdf5_str = "hdf5@1.0 ^gmake@4.1"
+ pinned_str = "pinned-gmake@1.0 ^gmake@3.0"
+ input_specs = [Spec(hdf5_str), Spec(pinned_str)]
+ solver = spack.solver.asp.Solver()
+ result = solver.solve(input_specs)
+
+ assert any(x.satisfies(hdf5_str) for x in result.specs)
+ assert any(x.satisfies(pinned_str) for x in result.specs)
+
@pytest.mark.parametrize(
"v_str,v_opts,checksummed",