From d3c1f7a872a4097b74085b7275c338a1b52d96ae Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Thu, 25 Jan 2024 08:22:22 -0800 Subject: [PATCH] Fix using sticky variants in externals (#42253) --- lib/spack/spack/solver/asp.py | 13 ++++------ lib/spack/spack/test/concretize.py | 24 +++++++++++++++++++ .../sticky-variant-dependent/package.py | 17 +++++++++++++ 3 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 var/spack/repos/builtin.mock/packages/sticky-variant-dependent/package.py diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 3661aa9b9b..151aef20a6 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1768,15 +1768,12 @@ def external_packages(self): for local_idx, spec in enumerate(external_specs): msg = "%s available as external when satisfying %s" % (spec.name, spec) - def external_imposition(input_spec, _): - return [fn.attr("external_conditions_hold", input_spec.name, local_idx)] + def external_imposition(input_spec, requirements): + return requirements + [ + fn.attr("external_conditions_hold", input_spec.name, local_idx) + ] - self.condition( - spec, - spack.spec.Spec(spec.name), - msg=msg, - transform_imposed=external_imposition, - ) + self.condition(spec, spec, msg=msg, transform_imposed=external_imposition) self.possible_versions[spec.name].add(spec.version) self.gen.newline() diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 70743d8704..41b0eb600f 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -1522,6 +1522,30 @@ def test_sticky_variant_in_package(self): s = Spec("sticky-variant %clang").concretized() assert s.satisfies("%clang") and s.satisfies("~allow-gcc") + @pytest.mark.regression("42172") + @pytest.mark.only_clingo("Original concretizer cannot use sticky variants") + @pytest.mark.parametrize( + "spec,allow_gcc", + [ + ("sticky-variant@1.0+allow-gcc", True), + ("sticky-variant@1.0~allow-gcc", False), + ("sticky-variant@1.0", False), + ], + ) + def test_sticky_variant_in_external(self, spec, allow_gcc): + # setup external for sticky-variant+allow-gcc + config = {"externals": [{"spec": spec, "prefix": "/fake/path"}], "buildable": False} + spack.config.set("packages:sticky-variant", config) + + maybe = llnl.util.lang.nullcontext if allow_gcc else pytest.raises + with maybe(spack.error.SpackError): + s = Spec("sticky-variant-dependent%gcc").concretized() + + if allow_gcc: + assert s.satisfies("%gcc") + assert s["sticky-variant"].satisfies("+allow-gcc") + assert s["sticky-variant"].external + @pytest.mark.only_clingo("Use case not supported by the original concretizer") def test_do_not_invent_new_concrete_versions_unless_necessary(self): # ensure we select a known satisfying version rather than creating diff --git a/var/spack/repos/builtin.mock/packages/sticky-variant-dependent/package.py b/var/spack/repos/builtin.mock/packages/sticky-variant-dependent/package.py new file mode 100644 index 0000000000..2036a31b28 --- /dev/null +++ b/var/spack/repos/builtin.mock/packages/sticky-variant-dependent/package.py @@ -0,0 +1,17 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) +from spack.package import * + + +class StickyVariantDependent(AutotoolsPackage): + """Package with a sticky variant and a conflict""" + + homepage = "http://www.example.com" + url = "http://www.example.com/a-1.0.tar.gz" + + version("1.0", md5="0123456789abcdef0123456789abcdef") + + depends_on("sticky-variant") + conflicts("%gcc", when="^sticky-variant~allow-gcc")