From 3a5e48f47686f2ed8ec296dccba81087010b2814 Mon Sep 17 00:00:00 2001 From: Alec Scott Date: Wed, 19 Apr 2023 01:00:40 -0700 Subject: installer.py: drop build edges of installed packages by default (#36707) This means that `spack install` will now build the minimal set of packages required to install the root(s). To opt out of build edge pruning, use `spack install --include-build-deps`. Co-authored-by: Harmen Stoppels --- lib/spack/spack/installer.py | 5 +++- lib/spack/spack/test/installer.py | 48 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py index 045e543e8c..4908fa7788 100644 --- a/lib/spack/spack/installer.py +++ b/lib/spack/spack/installer.py @@ -2420,7 +2420,10 @@ class BuildRequest(object): else: cache_only = self.install_args.get("dependencies_cache_only") - if not cache_only or include_build_deps: + # Include build dependencies if pkg is not installed and cache_only + # is False, or if build depdencies are explicitly called for + # by include_build_deps. + if include_build_deps or not (cache_only or pkg.spec.installed): deptypes.append("build") if self.run_tests(pkg): deptypes.append("test") diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py index 76e987e1cd..4e92802b72 100644 --- a/lib/spack/spack/test/installer.py +++ b/lib/spack/spack/test/installer.py @@ -252,6 +252,54 @@ def test_installer_str(install_mockery): assert "failed (0)" in istr +def test_installer_prune_built_build_deps(install_mockery, monkeypatch, tmpdir): + r""" + Ensure that build dependencies of installed deps are pruned + from installer package queues. + + (a) + / \ + / \ + (b) (c) <--- is installed already so we should + \ / | \ prune (f) from this install since + \ / | \ it is *only* needed to build (b) + (d) (e) (f) + + Thus since (c) is already installed our build_pq dag should + only include four packages. [(a), (b), (c), (d), (e)] + """ + + @property + def _mock_installed(self): + return self.name in ["c"] + + # Mock the installed property to say that (b) is installed + monkeypatch.setattr(spack.spec.Spec, "installed", _mock_installed) + + # Create mock repository with packages (a), (b), (c), (d), and (e) + builder = spack.repo.MockRepositoryBuilder(tmpdir.mkdir("mock-repo")) + + builder.add_package("a", dependencies=[("b", "build", None), ("c", "build", None)]) + builder.add_package("b", dependencies=[("d", "build", None)]) + builder.add_package( + "c", dependencies=[("d", "build", None), ("e", "all", None), ("f", "build", None)] + ) + builder.add_package("d") + builder.add_package("e") + builder.add_package("f") + + with spack.repo.use_repositories(builder.root): + const_arg = installer_args(["a"], {}) + installer = create_installer(const_arg) + + installer._init_queue() + + # Assert that (c) is not in the build_pq + result = set([task.pkg_id[0] for _, task in installer.build_pq]) + expected = set(["a", "b", "c", "d", "e"]) + assert result == expected + + def test_check_before_phase_error(install_mockery): s = spack.spec.Spec("trivial-install-test-package").concretized() s.package.stop_before_phase = "beforephase" -- cgit v1.2.3-60-g2f50