satisfies for conditional dependencies

Signed-off-by: Gregory Becker <becker33@llnl.gov>
This commit is contained in:
Gregory Becker 2025-04-24 15:50:46 -07:00
parent 89e0cf886d
commit 6eaaaa4ae7
No known key found for this signature in database
GPG Key ID: 2362541F6D14ED84

View File

@ -3447,6 +3447,10 @@ def satisfies(self, other: Union[str, "Spec"], deps: bool = True) -> bool:
lhs_edges: Dict[str, Set[DependencySpec]] = collections.defaultdict(set) lhs_edges: Dict[str, Set[DependencySpec]] = collections.defaultdict(set)
mock_nodes_from_old_specfiles = set() mock_nodes_from_old_specfiles = set()
for rhs_edge in other.traverse_edges(root=False, cover="edges"): for rhs_edge in other.traverse_edges(root=False, cover="edges"):
# Skip checking any conditional edge that is not satisfied
if rhs_edge.when != Spec() and not rhs_edge.parent.satisfies(rhs_edge.when):
continue
# If we are checking for ^mpi we need to verify if there is any edge # If we are checking for ^mpi we need to verify if there is any edge
if spack.repo.PATH.is_virtual(rhs_edge.spec.name): if spack.repo.PATH.is_virtual(rhs_edge.spec.name):
rhs_edge.update_virtuals(virtuals=(rhs_edge.spec.name,)) rhs_edge.update_virtuals(virtuals=(rhs_edge.spec.name,))
@ -3528,10 +3532,25 @@ def satisfies(self, other: Union[str, "Spec"], deps: bool = True) -> bool:
# Edges have been checked above already, hence deps=False # Edges have been checked above already, hence deps=False
lhs_nodes = [x for x in self.traverse(root=False)] + sorted(mock_nodes_from_old_specfiles) lhs_nodes = [x for x in self.traverse(root=False)] + sorted(mock_nodes_from_old_specfiles)
return all( for rhs in other.traverse(root=False):
any(lhs.satisfies(rhs, deps=False) for lhs in lhs_nodes) # Possible lhs nodes to match this rhs node
for rhs in other.traverse(root=False) lhss = [lhs for lhs in lhs_nodes if lhs.satisfies(rhs, deps=False)]
)
# Check whether the node needs matching (not a conditional that isn't satisfied)
in_edges = [
e
for e in rhs.edges_from_dependents()
if e.parent.satisfies(e.when)
or (lhss and all(lhs.satisfies(e.when) for lhs in lhss))
]
if not in_edges:
continue
# If there is no matching lhs for this rhs node
if not lhss:
return False
return True
@property # type: ignore[misc] # decorated prop not supported in mypy @property # type: ignore[misc] # decorated prop not supported in mypy
def patches(self): def patches(self):