summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Scheibel <scheibel1@llnl.gov>2023-03-20 12:30:33 -0700
committerGitHub <noreply@github.com>2023-03-20 12:30:33 -0700
commitc3e41153ac92f6ef92414024a8386d4ceec2615c (patch)
treedf09431d5db371e52c0a4d9904af4caa60e82248
parente1752ca3820690c158cd73fac9a9f322a44484c4 (diff)
downloadspack-c3e41153ac92f6ef92414024a8386d4ceec2615c.tar.gz
spack-c3e41153ac92f6ef92414024a8386d4ceec2615c.tar.bz2
spack-c3e41153ac92f6ef92414024a8386d4ceec2615c.tar.xz
spack-c3e41153ac92f6ef92414024a8386d4ceec2615c.zip
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).
-rw-r--r--lib/spack/spack/schema/packages.py15
-rw-r--r--lib/spack/spack/solver/asp.py11
-rw-r--r--lib/spack/spack/test/concretize_requirements.py18
3 files changed, 35 insertions, 9 deletions
diff --git a/lib/spack/spack/schema/packages.py b/lib/spack/spack/schema/packages.py
index 1f7c16e2d7..fe27557e68 100644
--- a/lib/spack/spack/schema/packages.py
+++ b/lib/spack/spack/schema/packages.py
@@ -32,11 +32,16 @@ properties = {
{
"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
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 42ce486233..8b9acd8b5e 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1017,9 +1017,14 @@ class SpackSolverSetup(object):
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):
diff --git a/lib/spack/spack/test/concretize_requirements.py b/lib/spack/spack/test/concretize_requirements.py
index 965d85e93d..f58cd87694 100644
--- a/lib/spack/spack/test/concretize_requirements.py
+++ b/lib/spack/spack/test/concretize_requirements.py
@@ -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: