traverse: w/o deptype (#42345)
Add the empty deptype `spack.deptypes.NONE`. Test the case `traverse_nodes(deptype=spack.deptypes.NONE)` to not traverse dependencies, only de-duplicate. Use the construct in environment views that otherwise would branch on whether deps are enabled or not.
This commit is contained in:
parent
62ed5ee318
commit
890ec8d71c
3 changed files with 25 additions and 14 deletions
|
@ -36,6 +36,9 @@
|
||||||
#: Default dependency type if none is specified
|
#: Default dependency type if none is specified
|
||||||
DEFAULT: DepFlag = BUILD | LINK
|
DEFAULT: DepFlag = BUILD | LINK
|
||||||
|
|
||||||
|
#: A flag with no dependency types set
|
||||||
|
NONE: DepFlag = 0
|
||||||
|
|
||||||
#: An iterator of all flag components
|
#: An iterator of all flag components
|
||||||
ALL_FLAGS: Tuple[DepFlag, DepFlag, DepFlag, DepFlag] = (BUILD, LINK, RUN, TEST)
|
ALL_FLAGS: Tuple[DepFlag, DepFlag, DepFlag, DepFlag] = (BUILD, LINK, RUN, TEST)
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
import llnl.util.tty.color as clr
|
import llnl.util.tty.color as clr
|
||||||
from llnl.util.lang import dedupe
|
|
||||||
from llnl.util.link_tree import ConflictingSpecsError
|
from llnl.util.link_tree import ConflictingSpecsError
|
||||||
from llnl.util.symlink import symlink
|
from llnl.util.symlink import symlink
|
||||||
|
|
||||||
|
@ -663,27 +662,23 @@ def __contains__(self, spec):
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def specs_for_view(self, concretized_root_specs):
|
def specs_for_view(self, concrete_roots: List[Spec]) -> List[Spec]:
|
||||||
"""
|
"""
|
||||||
From the list of concretized user specs in the environment, flatten
|
From the list of concretized user specs in the environment, flatten
|
||||||
the dags, and filter selected, installed specs, remove duplicates on dag hash.
|
the dags, and filter selected, installed specs, remove duplicates on dag hash.
|
||||||
"""
|
"""
|
||||||
# With deps, requires traversal
|
if self.link == "all":
|
||||||
if self.link == "all" or self.link == "run":
|
deptype = dt.LINK | dt.RUN
|
||||||
deptype = ("run") if self.link == "run" else ("link", "run")
|
elif self.link == "run":
|
||||||
specs = list(
|
deptype = dt.RUN
|
||||||
traverse.traverse_nodes(
|
|
||||||
concretized_root_specs, deptype=deptype, key=traverse.by_dag_hash
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
specs = list(dedupe(concretized_root_specs, key=traverse.by_dag_hash))
|
deptype = dt.NONE
|
||||||
|
|
||||||
|
specs = traverse.traverse_nodes(concrete_roots, deptype=deptype, key=traverse.by_dag_hash)
|
||||||
|
|
||||||
# Filter selected, installed specs
|
# Filter selected, installed specs
|
||||||
with spack.store.STORE.db.read_transaction():
|
with spack.store.STORE.db.read_transaction():
|
||||||
specs = [s for s in specs if s in self and s.installed]
|
return [s for s in specs if s in self and s.installed]
|
||||||
|
|
||||||
return specs
|
|
||||||
|
|
||||||
def regenerate(self, concretized_root_specs):
|
def regenerate(self, concretized_root_specs):
|
||||||
specs = self.specs_for_view(concretized_root_specs)
|
specs = self.specs_for_view(concretized_root_specs)
|
||||||
|
|
|
@ -395,3 +395,16 @@ def test_traverse_edges_topo(abstract_specs_toposort):
|
||||||
out_edge_indices = [i for (i, (parent, child)) in enumerate(edges) if node == parent]
|
out_edge_indices = [i for (i, (parent, child)) in enumerate(edges) if node == parent]
|
||||||
if in_edge_indices and out_edge_indices:
|
if in_edge_indices and out_edge_indices:
|
||||||
assert max(in_edge_indices) < min(out_edge_indices)
|
assert max(in_edge_indices) < min(out_edge_indices)
|
||||||
|
|
||||||
|
|
||||||
|
def test_traverse_nodes_no_deps(abstract_specs_dtuse):
|
||||||
|
"""Traversing nodes without deps should be the same as deduplicating the input specs. This may
|
||||||
|
not look useful, but can be used to avoid a branch on the call site in which it's otherwise
|
||||||
|
easy to forget to deduplicate input specs."""
|
||||||
|
inputs = [
|
||||||
|
abstract_specs_dtuse["dtuse"],
|
||||||
|
abstract_specs_dtuse["dtlink5"],
|
||||||
|
abstract_specs_dtuse["dtuse"], # <- duplicate
|
||||||
|
]
|
||||||
|
outputs = [x for x in traverse.traverse_nodes(inputs, deptype=dt.NONE)]
|
||||||
|
assert outputs == [abstract_specs_dtuse["dtuse"], abstract_specs_dtuse["dtlink5"]]
|
||||||
|
|
Loading…
Reference in a new issue