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:
parent
e1752ca382
commit
c3e41153ac
@ -32,11 +32,16 @@
|
|||||||
{
|
{
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"oneOf": [
|
||||||
"properties": {
|
{
|
||||||
"one_of": {"type": "array"},
|
"type": "object",
|
||||||
"any_of": {"type": "array"},
|
"properties": {
|
||||||
},
|
"one_of": {"type": "array"},
|
||||||
|
"any_of": {"type": "array"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{"type": "string"},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
# Shorthand for a single requirement group with
|
# Shorthand for a single requirement group with
|
||||||
|
@ -1017,9 +1017,14 @@ def _rules_from_requirements(self, pkg_name, requirements):
|
|||||||
else:
|
else:
|
||||||
rules = []
|
rules = []
|
||||||
for requirement in requirements:
|
for requirement in requirements:
|
||||||
for policy in ("one_of", "any_of"):
|
if isinstance(requirement, str):
|
||||||
if policy in requirement:
|
# A string represents a spec that must be satisfied. It is
|
||||||
rules.append((pkg_name, policy, requirement[policy]))
|
# 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
|
return rules
|
||||||
|
|
||||||
def pkg_rules(self, pkg, tests):
|
def pkg_rules(self, pkg, tests):
|
||||||
|
@ -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):
|
def test_requirement_isnt_optional(concretize_scope, test_repo):
|
||||||
"""If a user spec requests something that directly conflicts
|
"""If a user spec requests something that directly conflicts
|
||||||
with a requirement, make sure we get an error.
|
with a requirement, make sure we get an error.
|
||||||
"""
|
"""
|
||||||
if spack.config.get("config:concretizer") == "original":
|
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 = """\
|
conf_str = """\
|
||||||
packages:
|
packages:
|
||||||
|
Loading…
Reference in New Issue
Block a user