env: continue to mark non-roots as implicitly installed on partial env installs (#47183)

Fixes a change in behavior/bug in
70412612c7, where partial environment
installs would mark the selected spec as explicitly installed, even if
it was not a root of the environment.

The desired behavior is that roots by definition are the to be
explicitly installed specs. The specs on the `spack -e ... install x`
command line are just filters for partial installs, so leave them
implicitly installed if they aren't roots.
This commit is contained in:
Harmen Stoppels 2024-10-23 23:17:40 +02:00 committed by Harmen Stoppels
parent 67e5b4fecf
commit 05dcd1d2b7
2 changed files with 23 additions and 10 deletions

View File

@ -1936,17 +1936,16 @@ def install_specs(self, specs: Optional[List[Spec]] = None, **install_args):
specs = specs if specs is not None else roots
# Extend the set of specs to overwrite with modified dev specs and their parents
overwrite: Set[str] = set()
overwrite.update(install_args.get("overwrite", []), self._dev_specs_that_need_overwrite())
install_args["overwrite"] = overwrite
install_args["overwrite"] = {
*install_args.get("overwrite", ()),
*self._dev_specs_that_need_overwrite(),
}
explicit: Set[str] = set()
explicit.update(
install_args.get("explicit", []),
(s.dag_hash() for s in specs),
(s.dag_hash() for s in roots),
)
install_args["explicit"] = explicit
# Only environment roots are marked explicit
install_args["explicit"] = {
*install_args.get("explicit", ()),
*(s.dag_hash() for s in roots),
}
PackageInstaller([spec.package for spec in specs], install_args).install()

View File

@ -843,3 +843,17 @@ def test_root_version_weights_for_old_versions(mutable_mock_env_path, mock_packa
assert bowtie.satisfies("@=1.3.0")
assert gcc.satisfies("@=1.0")
def test_only_roots_are_explicitly_installed(tmp_path, mock_packages, config, temporary_store):
"""When installing specific non-root specs from an environment, we continue to mark them
as implicitly installed. What makes installs explicit is that they are root of the env."""
env = ev.create_in_dir(tmp_path)
env.add("mpileaks")
env.concretize()
mpileaks = env.concrete_roots()[0]
callpath = mpileaks["callpath"]
env.install_specs([callpath], fake=True)
assert callpath in temporary_store.db.query(explicit=False)
env.install_specs([mpileaks], fake=True)
assert temporary_store.db.query(explicit=True) == [mpileaks]