improve static check of direct deps
This commit is contained in:
parent
cfaf130115
commit
9fb5878ebb
@ -4507,36 +4507,30 @@ def __init__(self):
|
|||||||
self.selector = ReusableSpecsSelector(configuration=spack.config.CONFIG)
|
self.selector = ReusableSpecsSelector(configuration=spack.config.CONFIG)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _check_input_and_extract_concrete_specs(specs):
|
def _check_input_and_extract_concrete_specs(
|
||||||
reusable = []
|
specs: List[spack.spec.Spec],
|
||||||
|
) -> List[spack.spec.Spec]:
|
||||||
|
reusable: List[spack.spec.Spec] = []
|
||||||
|
analyzer = create_graph_analyzer()
|
||||||
for root in specs:
|
for root in specs:
|
||||||
for s in root.traverse():
|
for s in root.traverse():
|
||||||
candidates = s.edges_to_dependencies(depflag=dt.BUILD)
|
|
||||||
if candidates:
|
|
||||||
non_virtuals, virtuals, _ = create_graph_analyzer().possible_dependencies(
|
|
||||||
s, transitive=False, allowed_deps=dt.LINK | dt.RUN | dt.BUILD
|
|
||||||
)
|
|
||||||
possible_direct_deps = set(non_virtuals) | virtuals
|
|
||||||
not_possible = set(
|
|
||||||
[
|
|
||||||
x.spec.name
|
|
||||||
for x in candidates
|
|
||||||
if x.direct and x.spec.name not in possible_direct_deps
|
|
||||||
]
|
|
||||||
)
|
|
||||||
if not_possible:
|
|
||||||
start_str = f"'{s}' in '{root}'"
|
|
||||||
if s == root:
|
|
||||||
start_str = f"'{root}'"
|
|
||||||
raise UnsatisfiableSpecError(
|
|
||||||
f"{start_str} cannot have a dependency on {', '.join(not_possible)}, "
|
|
||||||
f"according to its recipe"
|
|
||||||
)
|
|
||||||
|
|
||||||
if s.concrete:
|
if s.concrete:
|
||||||
reusable.append(s)
|
reusable.append(s)
|
||||||
elif spack.repo.PATH.is_virtual(s.name):
|
else:
|
||||||
continue
|
if spack.repo.PATH.is_virtual(s.name):
|
||||||
|
continue
|
||||||
|
# Error if direct dependencies cannot be satisfied
|
||||||
|
deps = {edge.spec.name for edge in s.edges_to_dependencies() if edge.direct}
|
||||||
|
if deps:
|
||||||
|
graph = analyzer.possible_dependencies(
|
||||||
|
s, allowed_deps=dt.ALL, transitive=False
|
||||||
|
)
|
||||||
|
deps.difference_update(graph.real_pkgs, graph.virtuals)
|
||||||
|
if deps:
|
||||||
|
start_str = f"'{root}'" if s == root else f"'{s}' in '{root}'"
|
||||||
|
raise UnsatisfiableSpecError(
|
||||||
|
f"{start_str} cannot depend on {', '.join(deps)}"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
spack.repo.PATH.get_pkg_class(s.fullname)
|
spack.repo.PATH.get_pkg_class(s.fullname)
|
||||||
|
@ -2199,7 +2199,7 @@ def test_unsolved_specs_raises_error(self, monkeypatch, mock_packages):
|
|||||||
# A package does not exist
|
# A package does not exist
|
||||||
("pkg-a ^foo", "since 'foo' does not exist"),
|
("pkg-a ^foo", "since 'foo' does not exist"),
|
||||||
# Request a compiler for a package that doesn't need it
|
# Request a compiler for a package that doesn't need it
|
||||||
("pkg-c %gcc", "according to its recipe"),
|
("pkg-c %gcc", "cannot depend on gcc"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_errors_on_statically_checked_preconditions(self, spec_str, expected_match):
|
def test_errors_on_statically_checked_preconditions(self, spec_str, expected_match):
|
||||||
|
Loading…
Reference in New Issue
Block a user