Fix filtering external specs (#44093)
When an include filter on externals is present, implicitly include libcs. Also, do not penalize deprecated versions if they come from externals.
This commit is contained in:
parent
189ae4b06e
commit
f55224f161
4 changed files with 64 additions and 0 deletions
|
@ -1649,11 +1649,15 @@ def external_packages(self):
|
||||||
if isinstance(reuse_yaml, typing.Mapping):
|
if isinstance(reuse_yaml, typing.Mapping):
|
||||||
default_include = reuse_yaml.get("include", [])
|
default_include = reuse_yaml.get("include", [])
|
||||||
default_exclude = reuse_yaml.get("exclude", [])
|
default_exclude = reuse_yaml.get("exclude", [])
|
||||||
|
libc_externals = list(all_libcs())
|
||||||
for source in reuse_yaml.get("from", []):
|
for source in reuse_yaml.get("from", []):
|
||||||
if source["type"] != "external":
|
if source["type"] != "external":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
include = source.get("include", default_include)
|
include = source.get("include", default_include)
|
||||||
|
if include:
|
||||||
|
# Since libcs are implicit externals, we need to implicitly include them
|
||||||
|
include = include + libc_externals
|
||||||
exclude = source.get("exclude", default_exclude)
|
exclude = source.get("exclude", default_exclude)
|
||||||
spec_filters.append(
|
spec_filters.append(
|
||||||
SpecFilter(
|
SpecFilter(
|
||||||
|
|
|
@ -1424,6 +1424,7 @@ opt_criterion(73, "deprecated versions used").
|
||||||
#minimize{
|
#minimize{
|
||||||
1@73+Priority,PackageNode
|
1@73+Priority,PackageNode
|
||||||
: attr("deprecated", PackageNode, _),
|
: attr("deprecated", PackageNode, _),
|
||||||
|
not external(PackageNode),
|
||||||
build_priority(PackageNode, Priority)
|
build_priority(PackageNode, Priority)
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
|
|
@ -2464,6 +2464,7 @@ def test_spec_with_build_dep_from_json(self, tmp_path):
|
||||||
assert s["dttop"].dag_hash() == build_dep.dag_hash()
|
assert s["dttop"].dag_hash() == build_dep.dag_hash()
|
||||||
|
|
||||||
@pytest.mark.regression("44040")
|
@pytest.mark.regression("44040")
|
||||||
|
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
||||||
def test_exclude_specs_from_reuse(self, monkeypatch):
|
def test_exclude_specs_from_reuse(self, monkeypatch):
|
||||||
"""Tests that we can exclude a spec from reuse when concretizing, and that the spec
|
"""Tests that we can exclude a spec from reuse when concretizing, and that the spec
|
||||||
is not added back to the solve as a dependency of another reusable spec.
|
is not added back to the solve as a dependency of another reusable spec.
|
||||||
|
@ -2503,6 +2504,48 @@ def test_exclude_specs_from_reuse(self, monkeypatch):
|
||||||
for dep in result["dyninst"].traverse(root=False):
|
for dep in result["dyninst"].traverse(root=False):
|
||||||
assert dep.dag_hash() == reused[dep.name].dag_hash()
|
assert dep.dag_hash() == reused[dep.name].dag_hash()
|
||||||
|
|
||||||
|
@pytest.mark.regression("44091")
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"included_externals",
|
||||||
|
[
|
||||||
|
["deprecated-versions"],
|
||||||
|
# Try the empty list, to ensure that in that case everything will be included
|
||||||
|
# since filtering should happen only when the list is non-empty
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
|
||||||
|
def test_include_specs_from_externals_and_libcs(
|
||||||
|
self, included_externals, mutable_config, tmp_path
|
||||||
|
):
|
||||||
|
"""Tests that when we include specs from externals, we always include libcs."""
|
||||||
|
mutable_config.set(
|
||||||
|
"packages",
|
||||||
|
{
|
||||||
|
"deprecated-versions": {
|
||||||
|
"externals": [{"spec": "deprecated-versions@1.1.0", "prefix": str(tmp_path)}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
request_str = "deprecated-client"
|
||||||
|
|
||||||
|
# When using the external the version is selected even if deprecated
|
||||||
|
with spack.config.override(
|
||||||
|
"concretizer:reuse", {"from": [{"type": "external", "include": included_externals}]}
|
||||||
|
):
|
||||||
|
result = Spec(request_str).concretized()
|
||||||
|
|
||||||
|
assert result["deprecated-versions"].satisfies("@1.1.0")
|
||||||
|
|
||||||
|
# When excluding it, we pick the non-deprecated version
|
||||||
|
with spack.config.override(
|
||||||
|
"concretizer:reuse",
|
||||||
|
{"from": [{"type": "external", "exclude": ["deprecated-versions"]}]},
|
||||||
|
):
|
||||||
|
result = Spec(request_str).concretized()
|
||||||
|
|
||||||
|
assert result["deprecated-versions"].satisfies("@1.0.0")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def duplicates_test_repository():
|
def duplicates_test_repository():
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# 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 DeprecatedClient(Package):
|
||||||
|
"""A package depending on another which has deprecated versions."""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/c-1.0.tar.gz"
|
||||||
|
|
||||||
|
version("1.1.0", sha256="abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890")
|
||||||
|
|
||||||
|
depends_on("deprecated-versions")
|
Loading…
Reference in a new issue