conditional variant values: allow boolean (#33939)

This commit is contained in:
Greg Becker 2022-11-30 23:25:57 -08:00 committed by GitHub
parent 99fcc57607
commit b139cab687
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 17 deletions

View File

@ -1017,17 +1017,35 @@ def pkg_rules(self, pkg, tests):
values = [variant.default]
for value in sorted(values):
if getattr(value, "when", True) is not True: # when=True means unconditional
condition_spec = spack.spec.Spec("{0}={1}".format(name, value))
if value.when is False:
# This value is a conflict
# Cannot just prevent listing it as a possible value because it could
# also come in as a possible value from the command line
trigger_id = self.condition(
condition_spec,
name=pkg.name,
msg="invalid variant value {0}={1}".format(name, value),
)
constraint_id = self.condition(
spack.spec.Spec(),
name=pkg.name,
msg="empty (total) conflict constraint",
)
msg = "variant {0}={1} is conditionally disabled".format(name, value)
self.gen.fact(fn.conflict(pkg.name, trigger_id, constraint_id, msg))
else:
imposed = spack.spec.Spec(value.when)
imposed.name = pkg.name
self.condition(
required_spec=condition_spec,
imposed_spec=imposed,
name=pkg.name,
msg="%s variant %s value %s when %s" % (pkg.name, name, value, when),
)
self.gen.fact(fn.variant_possible_value(pkg.name, name, value))
if hasattr(value, "when"):
required = spack.spec.Spec("{0}={1}".format(name, value))
imposed = spack.spec.Spec(value.when)
imposed.name = pkg.name
self.condition(
required_spec=required,
imposed_spec=imposed,
name=pkg.name,
msg="%s variant %s value %s when %s" % (pkg.name, name, value, when),
)
if variant.sticky:
self.gen.fact(fn.variant_sticky(pkg.name, name))

View File

@ -1481,21 +1481,25 @@ def test_do_not_invent_new_concrete_versions_unless_necessary(self):
assert ver("2.7.21") == Spec("python@2.7.21").concretized().version
@pytest.mark.parametrize(
"spec_str",
"spec_str,valid",
[
"conditional-values-in-variant@1.62.0 cxxstd=17",
"conditional-values-in-variant@1.62.0 cxxstd=2a",
"conditional-values-in-variant@1.72.0 cxxstd=2a",
("conditional-values-in-variant@1.62.0 cxxstd=17", False),
("conditional-values-in-variant@1.62.0 cxxstd=2a", False),
("conditional-values-in-variant@1.72.0 cxxstd=2a", False),
# Ensure disjoint set of values work too
"conditional-values-in-variant@1.72.0 staging=flexpath",
("conditional-values-in-variant@1.72.0 staging=flexpath", False),
# Ensure conditional values set False fail too
("conditional-values-in-variant foo=bar", False),
("conditional-values-in-variant foo=foo", True),
],
)
def test_conditional_values_in_variants(self, spec_str):
def test_conditional_values_in_variants(self, spec_str, valid):
if spack.config.get("config:concretizer") == "original":
pytest.skip("Original concretizer doesn't resolve conditional values in variants")
s = Spec(spec_str)
with pytest.raises((RuntimeError, spack.error.UnsatisfiableSpecError)):
raises = pytest.raises((RuntimeError, spack.error.UnsatisfiableSpecError))
with llnl.util.lang.nullcontext() if valid else raises:
s.concretize()
def test_conditional_values_in_conditional_variant(self):

View File

@ -38,3 +38,10 @@ class ConditionalValuesInVariant(Package):
values=any_combination_of(conditional("flexpath", "dataspaces", when="@1.73.0:")),
description="Enable dataspaces and/or flexpath staging transports",
)
variant(
"foo",
default="foo",
values=(conditional("foo", when=True), conditional("bar", when=False)),
description="Variant with default condition false",
)