Compare commits

...

5 Commits

Author SHA1 Message Date
Gregory Becker
89b4d2a33e wrote test case backwards 2025-02-10 15:20:46 -08:00
Gregory Becker
546e5a9a54 expand test further 2025-02-07 15:01:51 -08:00
Gregory Becker
401c183de9 expand on test and add comments on expected behaviors 2025-02-07 15:00:33 -08:00
Gregory Becker
b757500d9e add clarifying comment 2025-02-07 14:51:07 -08:00
Gregory Becker
2b759cf853 reuse: allow filtering by namespace 2025-02-07 10:54:49 +01:00
4 changed files with 44 additions and 1 deletions

View File

@ -34,6 +34,7 @@ an object, with the following keys:
1. ``roots``: if ``true`` root specs are reused, if ``false`` only dependencies of root specs are reused 1. ``roots``: if ``true`` root specs are reused, if ``false`` only dependencies of root specs are reused
2. ``from``: list of sources from which reused specs are taken 2. ``from``: list of sources from which reused specs are taken
3. ``namespaces``: list of namespaces from which to reuse specs, or the string ``"any"``.
Each source in ``from`` is itself an object: Each source in ``from`` is itself an object:
@ -56,6 +57,7 @@ For instance, the following configuration:
concretizer: concretizer:
reuse: reuse:
roots: true roots: true
namespaces: [builtin]
from: from:
- type: local - type: local
include: include:
@ -63,7 +65,8 @@ For instance, the following configuration:
- "%clang" - "%clang"
tells the concretizer to reuse all specs compiled with either ``gcc`` or ``clang``, that are installed tells the concretizer to reuse all specs compiled with either ``gcc`` or ``clang``, that are installed
in the local store. Any spec from remote buildcaches is disregarded. in the local store. Any spec from remote buildcaches is disregarded. Any spec from a namespace other than
Spack's builtin repo is disregarded.
To reduce the boilerplate in configuration files, default values for the ``include`` and To reduce the boilerplate in configuration files, default values for the ``include`` and
``exclude`` options can be pushed up one level: ``exclude`` options can be pushed up one level:

View File

@ -25,6 +25,12 @@
"roots": {"type": "boolean"}, "roots": {"type": "boolean"},
"include": LIST_OF_SPECS, "include": LIST_OF_SPECS,
"exclude": LIST_OF_SPECS, "exclude": LIST_OF_SPECS,
"namespaces": {
"oneOf": [
{"type": "string", "enum": ["any"]},
{"type": "array", "items": {"type": "string"}},
]
},
"from": { "from": {
"type": "array", "type": "array",
"items": { "items": {

View File

@ -3986,6 +3986,7 @@ def __init__(self, configuration: spack.config.Configuration) -> None:
self.configuration = configuration self.configuration = configuration
self.store = spack.store.create(configuration) self.store = spack.store.create(configuration)
self.reuse_strategy = ReuseStrategy.ROOTS self.reuse_strategy = ReuseStrategy.ROOTS
self.reuse_namespaces = "any"
reuse_yaml = self.configuration.get("concretizer:reuse", False) reuse_yaml = self.configuration.get("concretizer:reuse", False)
self.reuse_sources = [] self.reuse_sources = []
@ -4016,6 +4017,7 @@ def __init__(self, configuration: spack.config.Configuration) -> None:
self.reuse_strategy = ReuseStrategy.ROOTS self.reuse_strategy = ReuseStrategy.ROOTS
else: else:
self.reuse_strategy = ReuseStrategy.DEPENDENCIES self.reuse_strategy = ReuseStrategy.DEPENDENCIES
self.reuse_namespaces = reuse_yaml.get("namespaces", "any")
default_include = reuse_yaml.get("include", []) default_include = reuse_yaml.get("include", [])
default_exclude = reuse_yaml.get("exclude", []) default_exclude = reuse_yaml.get("exclude", [])
default_sources = [{"type": "local"}, {"type": "buildcache"}] default_sources = [{"type": "local"}, {"type": "buildcache"}]
@ -4083,6 +4085,9 @@ def reusable_specs(self, specs: List[spack.spec.Spec]) -> List[spack.spec.Spec]:
if self.reuse_strategy == ReuseStrategy.DEPENDENCIES: if self.reuse_strategy == ReuseStrategy.DEPENDENCIES:
result = [spec for spec in result if not any(root in spec for root in specs)] result = [spec for spec in result if not any(root in spec for root in specs)]
if self.reuse_namespaces != "any":
result = [spec for spec in result if spec.namespace in self.reuse_namespaces]
return result return result

View File

@ -1460,6 +1460,35 @@ def test_no_reuse_when_variant_condition_does_not_hold(self, mutable_database, m
new2 = spack.concretize.concretize_one("conditional-variant-pkg +two_whens") new2 = spack.concretize.concretize_one("conditional-variant-pkg +two_whens")
assert new2.satisfies("@2 +two_whens +version_based") assert new2.satisfies("@2 +two_whens +version_based")
def test_reuse_by_namespace(self, mutable_database, mock_packages):
spack.config.set("concretizer:reuse", True)
# Set spack to prefer an older version when doing new builds, but prioritize reuse higher
spack.config.set("packages:libelf", {"version": ["0.8.10"]})
# Expected behavior is to reuse the libelf@0.8.13 from mutable database
# despite configured preference for older version
reuse = spack.concretize.concretize_one("libelf")
assert reuse.installed
assert reuse.satisfies("@0.8.13")
# Reuse is turned off, so preference will be respected
spack.config.set("concretizer:reuse", {"namespaces": []})
noreuse = spack.concretize.concretize_one("libelf")
assert not noreuse.installed
assert noreuse.satisfies("@0.8.10")
# Expected behavior same as first concretization
spack.config.set("concretizer:reuse", {"namespaces": ["builtin.mock"]})
noreuse = spack.concretize.concretize_one("libelf")
assert noreuse.installed
assert noreuse.satisfies("@0.8.13")
# Expected behavior same as second concretization
spack.config.set("concretizer:reuse", {"namespaces": ["foobar"]})
noreuse = spack.concretize.concretize_one("libelf")
assert not noreuse.installed
assert noreuse.satisfies("@0.8.10")
def test_reuse_with_flags(self, mutable_database, mutable_config): def test_reuse_with_flags(self, mutable_database, mutable_config):
spack.config.set("concretizer:reuse", True) spack.config.set("concretizer:reuse", True)
spec = spack.concretize.concretize_one("pkg-a cflags=-g cxxflags=-g") spec = spack.concretize.concretize_one("pkg-a cflags=-g cxxflags=-g")