Package requirements: allow single specs in requirement lists (#36258)

If you have a "require:" section in your packages config, and you
use it to specify a list of requirements, the list elements can
now include strings (before this, each element in the list had to
be a `one_of` or `any_of` specification, which is awkward if you
wanted to apply just one spec with no alternatives).
This commit is contained in:
Peter Scheibel 2023-03-20 12:30:33 -07:00 committed by GitHub
parent e1752ca382
commit c3e41153ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 9 deletions

View File

@ -32,11 +32,16 @@
{
"type": "array",
"items": {
"type": "object",
"properties": {
"one_of": {"type": "array"},
"any_of": {"type": "array"},
},
"oneOf": [
{
"type": "object",
"properties": {
"one_of": {"type": "array"},
"any_of": {"type": "array"},
},
},
{"type": "string"},
]
},
},
# Shorthand for a single requirement group with

View File

@ -1017,9 +1017,14 @@ def _rules_from_requirements(self, pkg_name, requirements):
else:
rules = []
for requirement in requirements:
for policy in ("one_of", "any_of"):
if policy in requirement:
rules.append((pkg_name, policy, requirement[policy]))
if isinstance(requirement, str):
# A string represents a spec that must be satisfied. It is
# equivalent to a one_of group with a single element
rules.append((pkg_name, "one_of", [requirement]))
else:
for policy in ("one_of", "any_of"):
if policy in requirement:
rules.append((pkg_name, policy, requirement[policy]))
return rules
def pkg_rules(self, pkg, tests):

View File

@ -107,12 +107,28 @@ def fake_installs(monkeypatch, tmpdir):
)
def test_one_package_multiple_reqs(concretize_scope, test_repo):
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration requirements")
conf_str = """\
packages:
y:
require:
- "@2.4"
- "~shared"
"""
update_packages_config(conf_str)
y_spec = Spec("y").concretized()
assert y_spec.satisfies("@2.4~shared")
def test_requirement_isnt_optional(concretize_scope, test_repo):
"""If a user spec requests something that directly conflicts
with a requirement, make sure we get an error.
"""
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer does not support configuration" " requirements")
pytest.skip("Original concretizer does not support configuration requirements")
conf_str = """\
packages: