Don't drop build deps on overwrite install (#40252)
If you `spack install x ^y` where `y` is a pure build dep of `x`, and then uninstall `y`, and then `spack install --overwrite x ^y`, the build fails because `y` is not re-installed. Same can happen when you install a develop spec, run `spack gc`, modify sources, and install again; develop specs rely on overwrite install to work correctly.
This commit is contained in:
		@@ -847,10 +847,11 @@ def get_depflags(self, pkg: "spack.package_base.PackageBase") -> int:
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            cache_only = self.install_args.get("dependencies_cache_only")
 | 
					            cache_only = self.install_args.get("dependencies_cache_only")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Include build dependencies if pkg is not installed and cache_only
 | 
					        # Include build dependencies if pkg is going to be built from sources, or
 | 
				
			||||||
        # is False, or if build depdencies are explicitly called for
 | 
					        # if build deps are explicitly requested.
 | 
				
			||||||
        # by include_build_deps.
 | 
					        if include_build_deps or not (
 | 
				
			||||||
        if include_build_deps or not (cache_only or pkg.spec.installed):
 | 
					            cache_only or pkg.spec.installed and not pkg.spec.dag_hash() in self.overwrite
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
            depflag |= dt.BUILD
 | 
					            depflag |= dt.BUILD
 | 
				
			||||||
        if self.run_tests(pkg):
 | 
					        if self.run_tests(pkg):
 | 
				
			||||||
            depflag |= dt.TEST
 | 
					            depflag |= dt.TEST
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@
 | 
				
			|||||||
import spack.concretize
 | 
					import spack.concretize
 | 
				
			||||||
import spack.config
 | 
					import spack.config
 | 
				
			||||||
import spack.database
 | 
					import spack.database
 | 
				
			||||||
 | 
					import spack.deptypes as dt
 | 
				
			||||||
import spack.installer as inst
 | 
					import spack.installer as inst
 | 
				
			||||||
import spack.package_base
 | 
					import spack.package_base
 | 
				
			||||||
import spack.package_prefs as prefs
 | 
					import spack.package_prefs as prefs
 | 
				
			||||||
@@ -1388,6 +1389,26 @@ def test_single_external_implicit_install(install_mockery, explicit_args, is_exp
 | 
				
			|||||||
    assert spack.store.STORE.db.get_record(pkg).explicit == is_explicit
 | 
					    assert spack.store.STORE.db.get_record(pkg).explicit == is_explicit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_overwrite_install_does_install_build_deps(install_mockery, mock_fetch):
 | 
				
			||||||
 | 
					    """When overwrite installing something from sources, build deps should be installed."""
 | 
				
			||||||
 | 
					    s = spack.spec.Spec("dtrun3").concretized()
 | 
				
			||||||
 | 
					    create_installer([(s, {})]).install()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Verify there is a pure build dep
 | 
				
			||||||
 | 
					    edge = s.edges_to_dependencies(name="dtbuild3").pop()
 | 
				
			||||||
 | 
					    assert edge.depflag == dt.BUILD
 | 
				
			||||||
 | 
					    build_dep = edge.spec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Uninstall the build dep
 | 
				
			||||||
 | 
					    build_dep.package.do_uninstall()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Overwrite install the root dtrun3
 | 
				
			||||||
 | 
					    create_installer([(s, {"overwrite": [s.dag_hash()]})]).install()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Verify that the build dep was also installed.
 | 
				
			||||||
 | 
					    assert build_dep.installed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.parametrize("run_tests", [True, False])
 | 
					@pytest.mark.parametrize("run_tests", [True, False])
 | 
				
			||||||
def test_print_install_test_log_skipped(install_mockery, mock_packages, capfd, run_tests):
 | 
					def test_print_install_test_log_skipped(install_mockery, mock_packages, capfd, run_tests):
 | 
				
			||||||
    """Confirm printing of install log skipped if not run/no failures."""
 | 
					    """Confirm printing of install log skipped if not run/no failures."""
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user