refactor: Index requirements by when
spec
Part 3 of reworking all package metadata to key by `when` conditions. Changes conflict dictionary structure from this: { (requirement_spec, ...): [(when_spec, policy, msg)] } to this: { when_spec: [((requirement_spec, ...), policy, msg), ...] }
This commit is contained in:
parent
1bda594f70
commit
d2a9e3f871
4 changed files with 14 additions and 10 deletions
|
@ -967,10 +967,10 @@ def _extracts_errors(triggers, summary):
|
|||
summary = f"{pkg_name}: wrong 'when=' condition for the '{provided}' virtual"
|
||||
errors.extend(_extracts_errors(triggers, summary))
|
||||
|
||||
for _, triggers in pkg_cls.requirements.items():
|
||||
triggers = [when_spec for when_spec, _, _ in triggers]
|
||||
summary = f"{pkg_name}: wrong 'when=' condition in 'requires' directive"
|
||||
errors.extend(_extracts_errors(triggers, summary))
|
||||
for when, requirements, details in _error_items(pkg_cls.requirements):
|
||||
errors.append(
|
||||
error_cls(f"{pkg_name}: wrong 'when=' condition in 'requires' directive", details)
|
||||
)
|
||||
|
||||
for when, _, details in _error_items(pkg_cls.patches):
|
||||
errors.append(
|
||||
|
|
|
@ -965,7 +965,7 @@ def license(
|
|||
|
||||
|
||||
@directive("requirements")
|
||||
def requires(*requirement_specs, policy="one_of", when=None, msg=None):
|
||||
def requires(*requirement_specs: str, policy="one_of", when=None, msg=None):
|
||||
"""Allows a package to request a configuration to be present in all valid solutions.
|
||||
|
||||
For instance, a package that is known to compile only with GCC can declare:
|
||||
|
@ -984,7 +984,7 @@ def requires(*requirement_specs, policy="one_of", when=None, msg=None):
|
|||
msg: optional user defined message
|
||||
"""
|
||||
|
||||
def _execute_requires(pkg):
|
||||
def _execute_requires(pkg: "spack.package_base.PackageBase"):
|
||||
if policy not in ("one_of", "any_of"):
|
||||
err_msg = (
|
||||
f"the 'policy' argument of the 'requires' directive in {pkg.name} is set "
|
||||
|
@ -997,9 +997,10 @@ def _execute_requires(pkg):
|
|||
return
|
||||
|
||||
# Save in a list the requirements and the associated custom messages
|
||||
when_spec_list = pkg.requirements.setdefault(tuple(requirement_specs), [])
|
||||
requirement_list = pkg.requirements.setdefault(when_spec, [])
|
||||
msg_with_name = f"{pkg.name}: {msg}" if msg is not None else msg
|
||||
when_spec_list.append((when_spec, policy, msg_with_name))
|
||||
requirements = tuple(spack.spec.Spec(s) for s in requirement_specs)
|
||||
requirement_list.append((requirements, policy, msg_with_name))
|
||||
|
||||
return _execute_requires
|
||||
|
||||
|
|
|
@ -562,6 +562,9 @@ class PackageBase(WindowsRPath, PackageViewMixin, metaclass=PackageMeta):
|
|||
versions: dict
|
||||
dependencies: Dict["spack.spec.Spec", Dict[str, "spack.dependency.Dependency"]]
|
||||
conflicts: Dict["spack.spec.Spec", List[Tuple["spack.spec.Spec", Optional[str]]]]
|
||||
requirements: Dict[
|
||||
"spack.spec.Spec", List[Tuple[Tuple["spack.spec.Spec", ...], str, Optional[str]]]
|
||||
]
|
||||
patches: Dict["spack.spec.Spec", List["spack.patch.Patch"]]
|
||||
|
||||
#: By default, packages are not virtual
|
||||
|
|
|
@ -1303,8 +1303,8 @@ def package_requirement_rules(self, pkg):
|
|||
|
||||
def requirement_rules_from_package_py(self, pkg):
|
||||
rules = []
|
||||
for requirements, conditions in pkg.requirements.items():
|
||||
for when_spec, policy, message in conditions:
|
||||
for when_spec, requirement_list in pkg.requirements.items():
|
||||
for requirements, policy, message in requirement_list:
|
||||
rules.append(
|
||||
RequirementRule(
|
||||
pkg_name=pkg.name,
|
||||
|
|
Loading…
Reference in a new issue