From 5bae7428261fa06ec60d66d7437d329ac0962a1a Mon Sep 17 00:00:00 2001 From: Michael Kuhn <michael.kuhn@ovgu.de> Date: Tue, 14 Mar 2023 09:22:20 +0100 Subject: concretizer: add mode to reuse dependencies only (#30990) This adds a new mode for `concretizer:reuse` called `dependencies`, which only reuses dependencies. Currently, `spack install foo` will reuse older versions of `foo`, which might be surprising to users. --- lib/spack/spack/cmd/common/arguments.py | 10 +++++++++- lib/spack/spack/schema/concretizer.py | 4 +++- lib/spack/spack/solver/asp.py | 13 ++++++++++--- lib/spack/spack/test/cmd/common/arguments.py | 13 ++++++------- 4 files changed, 28 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py index 8302a43754..ae40f58fe0 100644 --- a/lib/spack/spack/cmd/common/arguments.py +++ b/lib/spack/spack/cmd/common/arguments.py @@ -514,7 +514,15 @@ def add_concretizer_args(subparser): dest="concretizer:reuse", const=True, default=None, - help="reuse installed dependencies/buildcaches when possible", + help="reuse installed packages/buildcaches when possible", + ) + subgroup.add_argument( + "--reuse-deps", + action=ConfigSetAction, + dest="concretizer:reuse", + const="dependencies", + default=None, + help="reuse installed dependencies only", ) diff --git a/lib/spack/spack/schema/concretizer.py b/lib/spack/spack/schema/concretizer.py index cb021271c3..a62786f404 100644 --- a/lib/spack/spack/schema/concretizer.py +++ b/lib/spack/spack/schema/concretizer.py @@ -14,7 +14,9 @@ properties = { "type": "object", "additionalProperties": False, "properties": { - "reuse": {"type": "boolean"}, + "reuse": { + "oneOf": [{"type": "boolean"}, {"type": "string", "enum": ["dependencies"]}] + }, "enable_node_namespace": {"type": "boolean"}, "targets": { "type": "object", diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 670dcf6ef9..1de346b80a 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -2502,7 +2502,7 @@ class Solver(object): spack.spec.Spec.ensure_valid_variants(s) return reusable - def _reusable_specs(self): + def _reusable_specs(self, specs): reusable_specs = [] if self.reuse: # Specs from the local Database @@ -2524,6 +2524,13 @@ class Solver(object): # TODO: update mirror configuration so it can indicate that the # TODO: source cache (or any mirror really) doesn't have binaries. pass + + # If we only want to reuse dependencies, remove the root specs + if self.reuse == "dependencies": + reusable_specs = [ + spec for spec in reusable_specs if not any(root in spec for root in specs) + ] + return reusable_specs def solve(self, specs, out=None, timers=False, stats=False, tests=False, setup_only=False): @@ -2540,7 +2547,7 @@ class Solver(object): """ # Check upfront that the variants are admissible reusable_specs = self._check_input_and_extract_concrete_specs(specs) - reusable_specs.extend(self._reusable_specs()) + reusable_specs.extend(self._reusable_specs(specs)) setup = SpackSolverSetup(tests=tests) output = OutputConfiguration(timers=timers, stats=stats, out=out, setup_only=setup_only) result, _, _ = self.driver.solve(setup, specs, reuse=reusable_specs, output=output) @@ -2563,7 +2570,7 @@ class Solver(object): tests (bool): add test dependencies to the solve """ reusable_specs = self._check_input_and_extract_concrete_specs(specs) - reusable_specs.extend(self._reusable_specs()) + reusable_specs.extend(self._reusable_specs(specs)) setup = SpackSolverSetup(tests=tests) # Tell clingo that we don't have to solve all the inputs at once diff --git a/lib/spack/spack/test/cmd/common/arguments.py b/lib/spack/spack/test/cmd/common/arguments.py index f3348259e6..e889fe55d8 100644 --- a/lib/spack/spack/test/cmd/common/arguments.py +++ b/lib/spack/spack/test/cmd/common/arguments.py @@ -122,19 +122,18 @@ def test_root_and_dep_match_returns_root(mock_packages, mutable_mock_env_path): assert env_spec2 -def test_concretizer_arguments(mutable_config, mock_packages): +@pytest.mark.parametrize( + "arg,config", [("--reuse", True), ("--fresh", False), ("--reuse-deps", "dependencies")] +) +def test_concretizer_arguments(mutable_config, mock_packages, arg, config): """Ensure that ConfigSetAction is doing the right thing.""" spec = spack.main.SpackCommand("spec") assert spack.config.get("concretizer:reuse", None) is None - spec("--reuse", "zlib") - - assert spack.config.get("concretizer:reuse", None) is True - - spec("--fresh", "zlib") + spec(arg, "zlib") - assert spack.config.get("concretizer:reuse", None) is False + assert spack.config.get("concretizer:reuse", None) == config def test_use_buildcache_type(): -- cgit v1.2.3-70-g09d2