package_base: break dependency on installer (#46423)

Removes `spack.package_base.PackageBase.do_{install,deprecate}` in favor of
`spack.installer.PackageInstaller.install` and `spack.installer.deprecate` resp.

That drops a dependency of `spack.package_base` on `spack.installer`, which is
necessary to get rid of circular dependencies in Spack.

Also change the signature of `PackageInstaller.__init__` from taking a dict as
positional argument, to an explicit list of keyword arguments.
This commit is contained in:
Harmen Stoppels 2024-09-19 23:25:36 +02:00 committed by GitHub
parent 098ad7ffc0
commit e4927b35d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 249 additions and 196 deletions

View File

@ -46,6 +46,7 @@
import spack.util.spack_yaml
import spack.util.url
import spack.version
from spack.installer import PackageInstaller
from ._common import _executables_in_store, _python_import, _root_spec, _try_import_from_store
from .clingo import ClingoBootstrapConcretizer
@ -277,7 +278,7 @@ def try_import(self, module: str, abstract_spec_str: str) -> bool:
# Install the spec that should make the module importable
with spack.config.override(self.mirror_scope):
concrete_spec.package.do_install(fail_fast=True)
PackageInstaller([concrete_spec.package], fail_fast=True).install()
if _try_import_from_store(module, query_spec=concrete_spec, query_info=info):
self.last_search = info
@ -300,7 +301,7 @@ def try_search_path(self, executables: Tuple[str], abstract_spec_str: str) -> bo
msg = "[BOOTSTRAP] Try installing '{0}' from sources"
tty.debug(msg.format(abstract_spec_str))
with spack.config.override(self.mirror_scope):
concrete_spec.package.do_install()
PackageInstaller([concrete_spec.package], fail_fast=True).install()
if _executables_in_store(executables, concrete_spec, query_info=info):
self.last_search = info
return True

View File

@ -20,6 +20,7 @@
import spack.cmd
import spack.environment as ev
import spack.installer
import spack.store
from spack.cmd.common import arguments
from spack.database import InstallStatuses
@ -142,4 +143,4 @@ def deprecate(parser, args):
tty.die("Will not deprecate any packages.")
for dcate, dcator in zip(all_deprecate, all_deprecators):
dcate.package.do_deprecate(dcator, symlink)
spack.installer.deprecate(dcate, dcator, symlink)

View File

@ -14,6 +14,7 @@
import spack.config
import spack.repo
from spack.cmd.common import arguments
from spack.installer import PackageInstaller
description = "developer build: build from code in current working directory"
section = "build"
@ -131,9 +132,9 @@ def dev_build(self, args):
elif args.test == "root":
tests = [spec.name for spec in specs]
spec.package.do_install(
PackageInstaller(
[spec.package],
tests=tests,
make_jobs=args.jobs,
keep_prefix=args.keep_prefix,
install_deps=not args.ignore_deps,
verbose=not args.quiet,
@ -141,7 +142,7 @@ def dev_build(self, args):
stop_before=args.before,
skip_patch=args.skip_patch,
stop_at=args.until,
)
).install()
# drop into the build environment of the package?
if args.shell is not None:

View File

@ -474,5 +474,5 @@ def install_without_active_env(args, install_kwargs, reporter_factory):
installs = [s.package for s in concrete_specs]
install_kwargs["explicit"] = [s.dag_hash() for s in concrete_specs]
builder = PackageInstaller(installs, install_kwargs)
builder = PackageInstaller(installs, **install_kwargs)
builder.install()

View File

@ -1967,7 +1967,7 @@ def install_specs(self, specs: Optional[List[Spec]] = None, **install_args):
)
install_args["explicit"] = explicit
PackageInstaller([spec.package for spec in specs], install_args).install()
PackageInstaller([spec.package for spec in specs], **install_args).install()
def all_specs_generator(self) -> Iterable[Spec]:
"""Returns a generator for all concrete specs"""

View File

@ -37,7 +37,7 @@
import time
from collections import defaultdict
from gzip import GzipFile
from typing import Dict, Iterator, List, Optional, Set, Tuple
from typing import Dict, Iterator, List, Optional, Set, Tuple, Union
import llnl.util.filesystem as fs
import llnl.util.lock as lk
@ -1053,8 +1053,87 @@ class PackageInstaller:
"""
def __init__(
self, packages: List["spack.package_base.PackageBase"], install_args: dict
self,
packages: List["spack.package_base.PackageBase"],
*,
cache_only: bool = False,
dependencies_cache_only: bool = False,
dependencies_use_cache: bool = True,
dirty: bool = False,
explicit: Union[Set[str], bool] = False,
overwrite: Optional[Union[List[str], Set[str]]] = None,
fail_fast: bool = False,
fake: bool = False,
include_build_deps: bool = False,
install_deps: bool = True,
install_package: bool = True,
install_source: bool = False,
keep_prefix: bool = False,
keep_stage: bool = False,
package_cache_only: bool = False,
package_use_cache: bool = True,
restage: bool = False,
skip_patch: bool = False,
stop_at: Optional[str] = None,
stop_before: Optional[str] = None,
tests: Union[bool, List[str], Set[str]] = False,
unsigned: Optional[bool] = None,
use_cache: bool = False,
verbose: bool = False,
) -> None:
"""
Arguments:
explicit: Set of package hashes to be marked as installed explicitly in the db. If
True, the specs from ``packages`` are marked explicit, while their dependencies are
not.
fail_fast: Fail if any dependency fails to install; otherwise, the default is to
install as many dependencies as possible (i.e., best effort installation).
fake: Don't really build; install fake stub files instead.
install_deps: Install dependencies before installing this package
install_source: By default, source is not installed, but for debugging it might be
useful to keep it around.
keep_prefix: Keep install prefix on failure. By default, destroys it.
keep_stage: By default, stage is destroyed only if there are no exceptions during
build. Set to True to keep the stage even with exceptions.
restage: Force spack to restage the package source.
skip_patch: Skip patch stage of build if True.
stop_before: stop execution before this installation phase (or None)
stop_at: last installation phase to be executed (or None)
tests: False to run no tests, True to test all packages, or a list of package names to
run tests for some
use_cache: Install from binary package, if available.
verbose: Display verbose build output (by default, suppresses it)
"""
if isinstance(explicit, bool):
explicit = {pkg.spec.dag_hash() for pkg in packages} if explicit else set()
install_args = {
"cache_only": cache_only,
"dependencies_cache_only": dependencies_cache_only,
"dependencies_use_cache": dependencies_use_cache,
"dirty": dirty,
"explicit": explicit,
"fail_fast": fail_fast,
"fake": fake,
"include_build_deps": include_build_deps,
"install_deps": install_deps,
"install_package": install_package,
"install_source": install_source,
"keep_prefix": keep_prefix,
"keep_stage": keep_stage,
"overwrite": overwrite or [],
"package_cache_only": package_cache_only,
"package_use_cache": package_use_cache,
"restage": restage,
"skip_patch": skip_patch,
"stop_at": stop_at,
"stop_before": stop_before,
"tests": tests,
"unsigned": unsigned,
"use_cache": use_cache,
"verbose": verbose,
}
# List of build requests
self.build_requests = [BuildRequest(pkg, install_args) for pkg in packages]
@ -1518,8 +1597,8 @@ def _install_task(self, task: BuildTask, install_status: InstallStatus) -> None:
spack.store.STORE.db.add(pkg.spec, explicit=explicit)
except spack.error.StopPhase as e:
# A StopPhase exception means that do_install was asked to
# stop early from clients, and is not an error at this point
# A StopPhase exception means that the installer was asked to stop early from clients,
# and is not an error at this point
pid = f"{self.pid}: " if tty.show_pid() else ""
tty.debug(f"{pid}{str(e)}")
tty.debug(f"Package stage directory: {pkg.stage.source_path}")
@ -2070,7 +2149,7 @@ def __init__(self, pkg: "spack.package_base.PackageBase", install_args: dict):
Arguments:
pkg: the package being installed.
install_args: arguments to do_install() from parent process.
install_args: arguments to the installer from parent process.
"""
self.pkg = pkg
@ -2274,7 +2353,7 @@ def build_process(pkg: "spack.package_base.PackageBase", install_args: dict) ->
Arguments:
pkg: the package being installed.
install_args: arguments to do_install() from parent process.
install_args: arguments to installer from parent process.
"""
installer = BuildProcessInstaller(pkg, install_args)
@ -2284,6 +2363,33 @@ def build_process(pkg: "spack.package_base.PackageBase", install_args: dict) ->
return installer.run()
def deprecate(spec: "spack.spec.Spec", deprecator: "spack.spec.Spec", link_fn) -> None:
"""Deprecate this package in favor of deprecator spec"""
# Install deprecator if it isn't installed already
if not spack.store.STORE.db.query(deprecator):
PackageInstaller([deprecator.package], explicit=True).install()
old_deprecator = spack.store.STORE.db.deprecator(spec)
if old_deprecator:
# Find this spec file from its old deprecation
specfile = spack.store.STORE.layout.deprecated_file_path(spec, old_deprecator)
else:
specfile = spack.store.STORE.layout.spec_file_path(spec)
# copy spec metadata to "deprecated" dir of deprecator
depr_specfile = spack.store.STORE.layout.deprecated_file_path(spec, deprecator)
fs.mkdirp(os.path.dirname(depr_specfile))
shutil.copy2(specfile, depr_specfile)
# Any specs deprecated in favor of this spec are re-deprecated in favor of its new deprecator
for deprecated in spack.store.STORE.db.specs_deprecated_by(spec):
deprecate(deprecated, deprecator, link_fn)
# Now that we've handled metadata, uninstall and replace with link
spack.package_base.PackageBase.uninstall_by_spec(spec, force=True, deprecator=deprecator)
link_fn(deprecator.prefix, spec.prefix)
class OverwriteInstall:
def __init__(
self,

View File

@ -19,7 +19,6 @@
import io
import os
import re
import shutil
import sys
import textwrap
import time
@ -64,7 +63,6 @@
cache_extra_test_sources,
install_test_root,
)
from spack.installer import PackageInstaller
from spack.solver.version_order import concretization_version_order
from spack.stage import DevelopStage, ResourceStage, Stage, StageComposite, compute_stage_name
from spack.util.executable import ProcessError, which
@ -556,19 +554,16 @@ class PackageBase(WindowsRPath, PackageViewMixin, RedistributionMixin, metaclass
There are two main parts of a Spack package:
1. **The package class**. Classes contain ``directives``, which are
special functions, that add metadata (versions, patches,
dependencies, and other information) to packages (see
``directives.py``). Directives provide the constraints that are
used as input to the concretizer.
1. **The package class**. Classes contain ``directives``, which are special functions, that
add metadata (versions, patches, dependencies, and other information) to packages (see
``directives.py``). Directives provide the constraints that are used as input to the
concretizer.
2. **Package instances**. Once instantiated, a package is
essentially a software installer. Spack calls methods like
``do_install()`` on the ``Package`` object, and it uses those to
drive user-implemented methods like ``patch()``, ``install()``, and
other build steps. To install software, an instantiated package
needs a *concrete* spec, which guides the behavior of the various
install methods.
2. **Package instances**. Once instantiated, a package can be passed to the PackageInstaller.
It calls methods like ``do_stage()`` on the ``Package`` object, and it uses those to drive
user-implemented methods like ``patch()``, ``install()``, and other build steps. To
install software, an instantiated package needs a *concrete* spec, which guides the
behavior of the various install methods.
Packages are imported from repos (see ``repo.py``).
@ -590,7 +585,6 @@ class PackageBase(WindowsRPath, PackageViewMixin, RedistributionMixin, metaclass
p.do_fetch() # downloads tarball from a URL (or VCS)
p.do_stage() # expands tarball in a temp directory
p.do_patch() # applies patches to expanded source
p.do_install() # calls package's install() function
p.do_uninstall() # removes install directory
although packages that do not have code have nothing to fetch so omit
@ -1956,48 +1950,6 @@ def _resource_stage(self, resource):
resource_stage_folder = "-".join(pieces)
return resource_stage_folder
def do_install(self, **kwargs):
"""Called by commands to install a package and or its dependencies.
Package implementations should override install() to describe
their build process.
Args:
cache_only (bool): Fail if binary package unavailable.
dirty (bool): Don't clean the build environment before installing.
explicit (bool): True if package was explicitly installed, False
if package was implicitly installed (as a dependency).
fail_fast (bool): Fail if any dependency fails to install;
otherwise, the default is to install as many dependencies as
possible (i.e., best effort installation).
fake (bool): Don't really build; install fake stub files instead.
force (bool): Install again, even if already installed.
install_deps (bool): Install dependencies before installing this
package
install_source (bool): By default, source is not installed, but
for debugging it might be useful to keep it around.
keep_prefix (bool): Keep install prefix on failure. By default,
destroys it.
keep_stage (bool): By default, stage is destroyed only if there
are no exceptions during build. Set to True to keep the stage
even with exceptions.
restage (bool): Force spack to restage the package source.
skip_patch (bool): Skip patch stage of build if True.
stop_before (str): stop execution before this
installation phase (or None)
stop_at (str): last installation phase to be executed
(or None)
tests (bool or list or set): False to run no tests, True to test
all packages, or a list of package names to run tests for some
use_cache (bool): Install from binary package, if available.
verbose (bool): Display verbose build output (by default,
suppresses it)
"""
explicit = kwargs.get("explicit", True)
if isinstance(explicit, bool):
kwargs["explicit"] = {self.spec.dag_hash()} if explicit else set()
PackageInstaller([self], kwargs).install()
# TODO (post-34236): Update tests and all packages that use this as a
# TODO (post-34236): package method to the routine made available to
# TODO (post-34236): packages. Once done, remove this method.
@ -2454,35 +2406,6 @@ def do_uninstall(self, force=False):
# delegate to instance-less method.
PackageBase.uninstall_by_spec(self.spec, force)
def do_deprecate(self, deprecator, link_fn):
"""Deprecate this package in favor of deprecator spec"""
spec = self.spec
# Install deprecator if it isn't installed already
if not spack.store.STORE.db.query(deprecator):
deprecator.package.do_install()
old_deprecator = spack.store.STORE.db.deprecator(spec)
if old_deprecator:
# Find this specs yaml file from its old deprecation
self_yaml = spack.store.STORE.layout.deprecated_file_path(spec, old_deprecator)
else:
self_yaml = spack.store.STORE.layout.spec_file_path(spec)
# copy spec metadata to "deprecated" dir of deprecator
depr_yaml = spack.store.STORE.layout.deprecated_file_path(spec, deprecator)
fsys.mkdirp(os.path.dirname(depr_yaml))
shutil.copy2(self_yaml, depr_yaml)
# Any specs deprecated in favor of this spec are re-deprecated in
# favor of its new deprecator
for deprecated in spack.store.STORE.db.specs_deprecated_by(spec):
deprecated.package.do_deprecate(deprecator, link_fn)
# Now that we've handled metadata, uninstall and replace with link
PackageBase.uninstall_by_spec(spec, force=True, deprecator=deprecator)
link_fn(deprecator.prefix, spec.prefix)
def view(self):
"""Create a view with the prefix of this package as the root.
Extensions added to this view will modify the installation prefix of

View File

@ -11,13 +11,14 @@
import spack.binary_distribution as bd
import spack.mirror
import spack.spec
from spack.installer import PackageInstaller
pytestmark = pytest.mark.not_on_windows("does not run on windows")
def test_build_tarball_overwrite(install_mockery, mock_fetch, monkeypatch, tmp_path):
spec = spack.spec.Spec("trivial-install-test-package").concretized()
spec.package.do_install(fake=True)
PackageInstaller([spec.package], fake=True).install()
specs = [spec]

View File

@ -21,6 +21,7 @@
import spack.util.spack_yaml as syaml
from spack.build_environment import UseMode, _static_to_shared_library, dso_suffix
from spack.context import Context
from spack.installer import PackageInstaller
from spack.paths import build_env_path
from spack.util.environment import EnvironmentModifications
from spack.util.executable import Executable
@ -181,7 +182,7 @@ def test_setup_dependent_package_inherited_modules(
):
# This will raise on regression
s = spack.spec.Spec("cmake-client-inheritor").concretized()
s.package.do_install()
PackageInstaller([s.package]).install()
@pytest.mark.parametrize(

View File

@ -21,6 +21,7 @@
import spack.platforms
import spack.platforms.test
from spack.build_environment import ChildError, setup_package
from spack.installer import PackageInstaller
from spack.spec import Spec
from spack.util.executable import which
@ -144,7 +145,7 @@ def test_none_is_allowed(self, default_mock_concretization):
def test_libtool_archive_files_are_deleted_by_default(self, mutable_database):
# Install a package that creates a mock libtool archive
s = Spec("libtool-deletion").concretized()
s.package.do_install(explicit=True)
PackageInstaller([s.package], explicit=True).install()
# Assert the libtool archive is not there and we have
# a log of removed files
@ -160,7 +161,7 @@ def test_libtool_archive_files_might_be_installed_on_demand(
# patch its package to preserve the installation
s = Spec("libtool-deletion").concretized()
monkeypatch.setattr(type(s.package.builder), "install_libtool_archives", True)
s.package.do_install(explicit=True)
PackageInstaller([s.package], explicit=True).install()
# Assert libtool archives are installed
assert os.path.exists(s.package.builder.libtool_archive_file)
@ -171,7 +172,7 @@ def test_autotools_gnuconfig_replacement(self, mutable_database):
files from working alternatives from the gnuconfig package.
"""
s = Spec("autotools-config-replacement +patch_config_files +gnuconfig").concretized()
s.package.do_install()
PackageInstaller([s.package]).install()
with open(os.path.join(s.prefix.broken, "config.sub")) as f:
assert "gnuconfig version of config.sub" in f.read()
@ -190,7 +191,7 @@ def test_autotools_gnuconfig_replacement_disabled(self, mutable_database):
Tests whether disabling patch_config_files
"""
s = Spec("autotools-config-replacement ~patch_config_files +gnuconfig").concretized()
s.package.do_install()
PackageInstaller([s.package]).install()
with open(os.path.join(s.prefix.broken, "config.sub")) as f:
assert "gnuconfig version of config.sub" not in f.read()
@ -219,7 +220,7 @@ def test_autotools_gnuconfig_replacement_no_gnuconfig(self, mutable_database, mo
msg = "Cannot patch config files: missing dependencies: gnuconfig"
with pytest.raises(ChildError, match=msg):
s.package.do_install()
PackageInstaller([s.package]).install()
@pytest.mark.disable_clean_stage_check
def test_broken_external_gnuconfig(self, mutable_database, tmpdir):

View File

@ -19,6 +19,7 @@
import spack.mirror
import spack.spec
import spack.util.url
from spack.installer import PackageInstaller
from spack.spec import Spec
buildcache = spack.main.SpackCommand("buildcache")
@ -178,7 +179,7 @@ def test_buildcache_autopush(tmp_path, install_mockery, mock_fetch):
s = Spec("libdwarf").concretized()
# Install and generate build cache index
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
metadata_file = spack.binary_distribution.tarball_name(s, ".spec.json")
@ -379,7 +380,7 @@ def test_correct_specs_are_pushed(
things_to_install, expected, tmpdir, monkeypatch, default_mock_concretization, temporary_store
):
spec = default_mock_concretization("dttop")
spec.package.do_install(fake=True)
PackageInstaller([spec.package], explicit=True, fake=True).install()
slash_hash = f"/{spec.dag_hash()}"
class DontUpload(spack.binary_distribution.Uploader):
@ -438,13 +439,13 @@ def test_push_and_install_with_mirror_marked_unsigned_does_not_require_extra_fla
# Install
if signed:
# Need to pass "--no-check-signature" to avoid install errors
kwargs = {"cache_only": True, "unsigned": True}
kwargs = {"explicit": True, "cache_only": True, "unsigned": True}
else:
# No need to pass "--no-check-signature" if the mirror is unsigned
kwargs = {"cache_only": True}
kwargs = {"explicit": True, "cache_only": True}
spec.package.do_uninstall(force=True)
spec.package.do_install(**kwargs)
PackageInstaller([spec.package], **kwargs).install()
def test_skip_no_redistribute(mock_packages, config):
@ -489,7 +490,7 @@ def test_push_without_build_deps(tmp_path, temporary_store, mock_packages, mutab
mirror("add", "--unsigned", "my-mirror", str(tmp_path))
s = spack.spec.Spec("dtrun3").concretized()
s.package.do_install(fake=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
s["dtbuild3"].package.do_uninstall()
# fails when build deps are required

View File

@ -6,6 +6,7 @@
import pytest
from spack.installer import PackageInstaller
from spack.main import SpackCommand, SpackCommandError
from spack.spec import Spec
@ -15,10 +16,7 @@
@pytest.fixture
def python_database(mock_packages, mutable_database):
specs = [Spec(s).concretized() for s in ["python", "py-extension1", "py-extension2"]]
for spec in specs:
spec.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package for s in specs], explicit=True, fake=True).install()
yield

View File

@ -11,6 +11,7 @@
import spack.main
import spack.spec
import spack.traverse
from spack.installer import PackageInstaller
gc = spack.main.SpackCommand("gc")
add = spack.main.SpackCommand("add")
@ -27,7 +28,7 @@ def test_gc_without_build_dependency(mutable_database):
def test_gc_with_build_dependency(mutable_database):
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
assert "There are no unused specs." in gc("-yb")
assert "Successfully uninstalled cmake" in gc("-y")
@ -38,7 +39,7 @@ def test_gc_with_build_dependency(mutable_database):
def test_gc_with_environment(mutable_database, mutable_mock_env_path):
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
e = ev.create("test_gc")
with e:
@ -54,7 +55,7 @@ def test_gc_with_environment(mutable_database, mutable_mock_env_path):
def test_gc_with_build_dependency_in_environment(mutable_database, mutable_mock_env_path):
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
e = ev.create("test_gc")
with e:
@ -106,7 +107,7 @@ def test_gc_except_any_environments(mutable_database, mutable_mock_env_path):
def test_gc_except_specific_environments(mutable_database, mutable_mock_env_path):
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
assert mutable_database.query_local("zmpi")
@ -133,7 +134,7 @@ def test_gc_except_nonexisting_dir_env(mutable_database, mutable_mock_env_path,
def test_gc_except_specific_dir_env(mutable_database, mutable_mock_env_path, tmpdir):
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], explicit=True, fake=True).install()
assert mutable_database.query_local("zmpi")

View File

@ -28,6 +28,7 @@
import spack.package_base
import spack.store
from spack.error import SpackError, SpecSyntaxError
from spack.installer import PackageInstaller
from spack.main import SpackCommand
from spack.spec import Spec
@ -136,7 +137,7 @@ def test_package_output(tmpdir, capsys, install_mockery, mock_fetch):
# when nested AND in pytest
spec = Spec("printing-package").concretized()
pkg = spec.package
pkg.do_install(verbose=True)
PackageInstaller([pkg], explicit=True, verbose=True).install()
with gzip.open(pkg.install_log_path, "rt") as f:
out = f.read()
@ -261,7 +262,7 @@ def test_install_commit(mock_git_version_info, install_mockery, mock_packages, m
# Use the earliest commit in the respository
spec = Spec(f"git-test-commit@{commits[-1]}").concretized()
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
# Ensure first commit file contents were written
installed = os.listdir(spec.prefix.bin)

View File

@ -15,6 +15,7 @@
import spack.repo
import spack.spec
import spack.store
from spack.installer import PackageInstaller
module = spack.main.SpackCommand("module")
@ -184,8 +185,8 @@ def test_setdefault_command(mutable_database, mutable_config):
# Install two different versions of pkg-a
other_spec, preferred = "pkg-a@1.0", "pkg-a@2.0"
spack.spec.Spec(other_spec).concretized().package.do_install(fake=True)
spack.spec.Spec(preferred).concretized().package.do_install(fake=True)
specs = [spack.spec.Spec(other_spec).concretized(), spack.spec.Spec(preferred).concretized()]
PackageInstaller([s.package for s in specs], explicit=True, fake=True).install()
writers = {
preferred: writer_cls(spack.spec.Spec(preferred).concretized(), "default"),

View File

@ -6,6 +6,7 @@
import spack.main
import spack.repo
import spack.spec
from spack.installer import PackageInstaller
tags = spack.main.SpackCommand("tags")
@ -48,7 +49,7 @@ class tag_path:
def test_tags_installed(install_mockery, mock_fetch):
s = spack.spec.Spec("mpich").concretized()
s.package.do_install()
PackageInstaller([s.package], explicit=True, fake=True).install()
out = tags("-i")
for tag in ["tag1", "tag2"]:

View File

@ -8,6 +8,7 @@
import pytest
import spack.util.spack_yaml as s_yaml
from spack.installer import PackageInstaller
from spack.main import SpackCommand
from spack.spec import Spec
@ -180,7 +181,7 @@ def test_view_files_not_ignored(
):
spec = Spec("view-not-ignored").concretized()
pkg = spec.package
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
pkg.assert_installed(spec.prefix)
install("view-file") # Arbitrary package to add noise

View File

@ -33,6 +33,7 @@
import spack.util.file_cache
import spack.variant as vt
from spack.concretize import find_spec
from spack.installer import PackageInstaller
from spack.spec import CompilerSpec, Spec
from spack.version import Version, VersionList, ver
@ -1319,7 +1320,7 @@ def test_reuse_installed_packages_when_package_def_changes(
# Install a spec
root = Spec("root").concretized()
dependency = root["changing"].copy()
root.package.do_install(fake=True, explicit=True)
PackageInstaller([root.package], fake=True, explicit=True).install()
# Modify package.py
repo_with_changing_recipe.change(context)
@ -1345,7 +1346,7 @@ def test_no_reuse_when_variant_condition_does_not_hold(self, mutable_database, m
# Install a spec for which the `version_based` variant condition does not hold
old = Spec("conditional-variant-pkg @1").concretized()
old.package.do_install(fake=True, explicit=True)
PackageInstaller([old.package], fake=True, explicit=True).install()
# Then explicitly require a spec with `+version_based`, which shouldn't reuse previous spec
new1 = Spec("conditional-variant-pkg +version_based").concretized()
@ -1357,7 +1358,7 @@ def test_no_reuse_when_variant_condition_does_not_hold(self, mutable_database, m
def test_reuse_with_flags(self, mutable_database, mutable_config):
spack.config.set("concretizer:reuse", True)
spec = Spec("pkg-a cflags=-g cxxflags=-g").concretized()
spec.package.do_install(fake=True)
PackageInstaller([spec.package], fake=True, explicit=True).install()
testspec = Spec("pkg-a cflags=-g")
testspec.concretize()
@ -1658,7 +1659,7 @@ def test_delete_version_and_reuse(self, mutable_database, repo_with_changing_rec
declared in package.py
"""
root = Spec("root").concretized()
root.package.do_install(fake=True, explicit=True)
PackageInstaller([root.package], fake=True, explicit=True).install()
repo_with_changing_recipe.change({"delete_version": True})
with spack.config.override("concretizer:reuse", True):
@ -1676,7 +1677,7 @@ def test_installed_version_is_selected_only_for_reuse(
# Install a dependency that cannot be reused with "root"
# because of a conflict in a variant, then delete its version
dependency = Spec("changing@1.0~foo").concretized()
dependency.package.do_install(fake=True, explicit=True)
PackageInstaller([dependency.package], fake=True, explicit=True).install()
repo_with_changing_recipe.change({"delete_version": True})
with spack.config.override("concretizer:reuse", True):
@ -1691,7 +1692,7 @@ def test_reuse_with_unknown_namespace_dont_raise(
with spack.repo.use_repositories(mock_custom_repository, override=False):
s = Spec("pkg-c").concretized()
assert s.namespace != "builtin.mock"
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
with spack.config.override("concretizer:reuse", True):
s = Spec("pkg-c").concretized()
@ -1703,7 +1704,7 @@ def test_reuse_from_other_namespace_no_raise(self, tmpdir, temporary_store, monk
myrepo.add_package("zlib")
builtin = Spec("zlib").concretized()
builtin.package.do_install(fake=True, explicit=True)
PackageInstaller([builtin.package], fake=True, explicit=True).install()
with spack.repo.use_repositories(myrepo.root, override=False):
with spack.config.override("concretizer:reuse", True):
@ -1718,7 +1719,7 @@ def test_reuse_with_unknown_package_dont_raise(self, tmpdir, temporary_store, mo
with spack.repo.use_repositories(builder.root, override=False):
s = Spec("pkg-c").concretized()
assert s.namespace == "myrepo"
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
del sys.modules["spack.pkg.myrepo.pkg-c"]
del sys.modules["spack.pkg.myrepo"]
@ -1936,7 +1937,7 @@ def test_installed_externals_are_reused(
# Install the external spec
external1 = Spec("changing@1.0").concretized()
external1.package.do_install(fake=True, explicit=True)
PackageInstaller([external1.package], fake=True, explicit=True).install()
assert external1.external
# Modify the package.py file
@ -2309,7 +2310,7 @@ def test_reuse_python_from_cli_and_extension_from_db(self, mutable_database):
"""
s = Spec("py-extension1").concretized()
python_hash = s["python"].dag_hash()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
with spack.config.override("concretizer:reuse", True):
with_reuse = Spec(f"py-extension2 ^/{python_hash}").concretized()
@ -3023,7 +3024,7 @@ def test_spec_filters(specs, include, exclude, expected):
@pytest.mark.regression("38484")
def test_git_ref_version_can_be_reused(install_mockery, do_not_check_runtimes_on_reuse):
first_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5~opt").concretized()
first_spec.package.do_install(fake=True, explicit=True)
PackageInstaller([first_spec.package], fake=True, explicit=True).install()
with spack.config.override("concretizer:reuse", True):
# reproducer of the issue is that spack will solve when there is a change to the base spec
@ -3047,10 +3048,10 @@ def test_reuse_prefers_standard_over_git_versions(
so install git ref last and ensure it is not picked up by reuse
"""
standard_spec = spack.spec.Spec(f"git-ref-package@{standard_version}").concretized()
standard_spec.package.do_install(fake=True, explicit=True)
PackageInstaller([standard_spec.package], fake=True, explicit=True).install()
git_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5").concretized()
git_spec.package.do_install(fake=True, explicit=True)
PackageInstaller([git_spec.package], fake=True, explicit=True).install()
with spack.config.override("concretizer:reuse", True):
test_spec = spack.spec.Spec("git-ref-package@2").concretized()

View File

@ -14,6 +14,7 @@
import spack.solver.asp
import spack.util.spack_yaml as syaml
import spack.version
from spack.installer import PackageInstaller
from spack.solver.asp import InternalConcretizerError, UnsatisfiableSpecError
from spack.spec import Spec
from spack.util.url import path_to_file_url
@ -436,7 +437,7 @@ def test_reuse_oneof(concretize_scope, test_repo, tmp_path, mock_fetch):
store_dir = tmp_path / "store"
with spack.store.use_store(str(store_dir)):
s1 = Spec("y@2.5 ~shared").concretized()
s1.package.do_install(fake=True, explicit=True)
PackageInstaller([s1.package], fake=True, explicit=True).install()
update_packages_config(conf_str)

View File

@ -61,6 +61,7 @@
import spack.util.web
import spack.version
from spack.fetch_strategy import URLFetchStrategy
from spack.installer import PackageInstaller
from spack.util.pattern import Bunch
@ -852,7 +853,7 @@ def _populate(mock_db):
def _install(spec):
s = spack.spec.Spec(spec).concretized()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
_install("mpileaks ^mpich")
_install("mpileaks ^mpich2")

View File

@ -34,6 +34,7 @@
import spack.spec
import spack.store
import spack.version as vn
from spack.installer import PackageInstaller
from spack.schema.database_index import schema
from spack.util.executable import Executable
@ -385,7 +386,7 @@ def _check_remove_and_add_package(database: spack.database.Database, spec):
def _mock_install(spec: str):
s = spack.spec.Spec(spec).concretized()
s.package.do_install(fake=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
def _mock_remove(spec):
@ -713,7 +714,7 @@ def test_external_entries_in_db(mutable_database):
assert not rec.spec.external_modules
assert rec.explicit is False
rec.spec.package.do_install(fake=True, explicit=True)
PackageInstaller([rec.spec.package], fake=True, explicit=True).install()
rec = mutable_database.get_record("externaltool")
assert rec.spec.external_path == os.path.sep + os.path.join("path", "to", "external_tool")
assert not rec.spec.external_modules
@ -731,7 +732,7 @@ def test_regression_issue_8036(mutable_database, usr_folder_exists):
assert not s.installed
# Now install the external package and check again the `installed` property
s.package.do_install(fake=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
assert s.installed
@ -774,7 +775,7 @@ def test_query_unused_specs(mutable_database):
# This spec installs a fake cmake as a build only dependency
s = spack.spec.Spec("simple-inheritance")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
si = s.dag_hash()
ml_mpich = spack.store.STORE.db.query_one("mpileaks ^mpich").dag_hash()
@ -817,7 +818,7 @@ def test_query_spec_with_conditional_dependency(mutable_database):
# conditional on a Boolean variant
s = spack.spec.Spec("hdf5~mpi")
s.concretize()
s.package.do_install(fake=True, explicit=True)
PackageInstaller([s.package], fake=True, explicit=True).install()
results = spack.store.STORE.db.query_local("hdf5 ^mpich")
assert not results
@ -1144,7 +1145,7 @@ def test_reindex_with_upstreams(tmp_path, monkeypatch, mock_packages, config):
{"config": {"install_tree": {"root": str(tmp_path / "upstream")}}}
)
monkeypatch.setattr(spack.store, "STORE", upstream_store)
callpath.package.do_install(fake=True)
PackageInstaller([callpath.package], fake=True, explicit=True).install()
local_store = spack.store.create(
{
@ -1153,7 +1154,7 @@ def test_reindex_with_upstreams(tmp_path, monkeypatch, mock_packages, config):
}
)
monkeypatch.setattr(spack.store, "STORE", local_store)
mpileaks.package.do_install(fake=True)
PackageInstaller([mpileaks.package], fake=True, explicit=True).install()
# Sanity check that callpath is from upstream.
assert not local_store.db.query_local("callpath")
@ -1163,7 +1164,7 @@ def test_reindex_with_upstreams(tmp_path, monkeypatch, mock_packages, config):
# checks local installs before upstream databases, even when the local database is being
# reindexed.
monkeypatch.setattr(spack.store, "STORE", upstream_store)
mpileaks.package.do_install(fake=True)
PackageInstaller([mpileaks.package], fake=True, explicit=True).install()
# Delete the local database
shutil.rmtree(local_store.db.database_directory)

View File

@ -24,6 +24,7 @@
import spack.util.spack_json as sjson
from spack import binary_distribution
from spack.error import InstallError
from spack.installer import PackageInstaller
from spack.package_base import (
PackageBase,
PackageStillNeededError,
@ -42,7 +43,7 @@ def find_nothing(*args):
def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch):
spec = Spec("trivial-install-test-package").concretized()
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
assert spec.installed
spec.package.do_uninstall()
@ -54,7 +55,7 @@ def test_uninstall_non_existing_package(install_mockery, mock_fetch, monkeypatch
"""Ensure that we can uninstall a package that has been deleted from the repo"""
spec = Spec("trivial-install-test-package").concretized()
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
assert spec.installed
# Mock deletion of the package
@ -75,7 +76,7 @@ def test_pkg_attributes(install_mockery, mock_fetch, monkeypatch):
assert spec.concrete
pkg = spec.package
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
foo = "attributes-foo"
assert spec["bar"].prefix == spec[foo].prefix
assert spec["baz"].prefix == spec[foo].prefix
@ -132,7 +133,7 @@ def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch, wo
s.package.remove_prefix = mock_remove_prefix
with pytest.raises(MockInstallError):
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
assert os.path.isdir(s.package.prefix)
rm_prefix_checker = RemovePrefixChecker(instance_rm_prefix)
s.package.remove_prefix = rm_prefix_checker.remove_prefix
@ -141,7 +142,7 @@ def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch, wo
spack.store.STORE.failure_tracker.clear(s, True)
s.package.set_install_succeed()
s.package.do_install(restage=True)
PackageInstaller([s.package], explicit=True, restage=True).install()
assert rm_prefix_checker.removed
assert s.package.spec.installed
@ -160,12 +161,12 @@ def test_failing_overwrite_install_should_keep_previous_installation(
s.package.set_install_succeed()
# Do a failing overwrite install
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
s.package.set_install_fail()
kwargs = {"overwrite": [s.dag_hash()]}
with pytest.raises(Exception):
s.package.do_install(**kwargs)
PackageInstaller([s.package], explicit=True, **kwargs).install()
assert s.package.spec.installed
assert os.path.exists(s.prefix)
@ -174,7 +175,7 @@ def test_failing_overwrite_install_should_keep_previous_installation(
def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch, monkeypatch):
dependency = Spec("dependency-install")
dependency.concretize()
dependency.package.do_install()
PackageInstaller([dependency.package], explicit=True).install()
dependency_hash = dependency.dag_hash()
dependent = Spec("dependent-install ^/" + dependency_hash)
@ -192,7 +193,7 @@ def test_dont_add_patches_to_installed_package(install_mockery, mock_fetch, monk
def test_installed_dependency_request_conflicts(install_mockery, mock_fetch, mutable_mock_repo):
dependency = Spec("dependency-install")
dependency.concretize()
dependency.package.do_install()
PackageInstaller([dependency.package], explicit=True).install()
dependency_hash = dependency.dag_hash()
dependent = Spec("conflicting-dependent ^/" + dependency_hash)
@ -205,7 +206,7 @@ def test_install_dependency_symlinks_pkg(install_mockery, mock_fetch, mutable_mo
spec = Spec("flatten-deps")
spec.concretize()
pkg = spec.package
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
# Ensure dependency directory exists after the installation.
dependency_dir = os.path.join(pkg.prefix, "dependency-install")
@ -215,7 +216,7 @@ def test_install_dependency_symlinks_pkg(install_mockery, mock_fetch, mutable_mo
def test_install_times(install_mockery, mock_fetch, mutable_mock_repo):
"""Test install times added."""
spec = Spec("dev-build-test-install-phases").concretized()
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
# Ensure dependency directory exists after the installation.
install_times = os.path.join(spec.package.prefix, ".spack", spack_times_log)
@ -238,7 +239,7 @@ def test_flatten_deps(install_mockery, mock_fetch, mutable_mock_repo):
spec = Spec("dependent-install")
spec.concretize()
pkg = spec.package
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
# Demonstrate that the directory does not appear under the spec
# prior to the flatten operation.
@ -291,7 +292,7 @@ def test_installed_upstream_external(install_upstream, mock_fetch):
assert new_dependency.external
assert new_dependency.prefix == os.path.sep + os.path.join("path", "to", "external_tool")
dependent.package.do_install()
PackageInstaller([dependent.package], explicit=True).install()
assert not os.path.exists(new_dependency.prefix)
assert os.path.exists(dependent.prefix)
@ -310,7 +311,7 @@ def test_installed_upstream(install_upstream, mock_fetch):
assert new_dependency.installed_upstream
assert new_dependency.prefix == upstream_layout.path_for_spec(dependency)
dependent.package.do_install()
PackageInstaller([dependent.package], explicit=True).install()
assert not os.path.exists(new_dependency.prefix)
assert os.path.exists(dependent.prefix)
@ -323,14 +324,14 @@ def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch, w
# If remove_prefix is called at any point in this test, that is an error
monkeypatch.setattr(spack.package_base.PackageBase, "remove_prefix", mock_remove_prefix)
with pytest.raises(spack.build_environment.ChildError):
s.package.do_install(keep_prefix=True)
PackageInstaller([s.package], explicit=True, keep_prefix=True).install()
assert os.path.exists(s.package.prefix)
# must clear failure markings for the package before re-installing it
spack.store.STORE.failure_tracker.clear(s, True)
s.package.set_install_succeed()
s.package.do_install(keep_prefix=True)
PackageInstaller([s.package], explicit=True, keep_prefix=True).install()
assert s.package.spec.installed
@ -339,12 +340,12 @@ def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypa
monkeypatch.setattr(spack.package_base.PackageBase, "remove_prefix", mock_remove_prefix)
s.package.set_install_succeed()
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
assert s.package.spec.installed
# If Package.install is called after this point, it will fail
s.package.set_install_fail()
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdir):
@ -357,16 +358,16 @@ def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdi
with spack.config.override("config:checksum", False):
pkg_a = Spec("libelf@0.8.13").concretized().package
pkg_b = Spec("libelf@0.8.12").concretized().package
pkg_a.do_install()
PackageInstaller([pkg_a], explicit=True).install()
with pytest.raises(InstallError, match="Install prefix collision"):
pkg_b.do_install()
PackageInstaller([pkg_b], explicit=True).install()
def test_store(install_mockery, mock_fetch):
spec = Spec("cmake-client").concretized()
pkg = spec.package
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
@pytest.mark.disable_clean_stage_check
@ -375,7 +376,7 @@ def test_failing_build(install_mockery, mock_fetch, capfd):
pkg = spec.package
with pytest.raises(spack.build_environment.ChildError, match="Expected failure"):
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
class MockInstallError(spack.error.SpackError):
@ -404,7 +405,7 @@ def test_nosource_pkg_install(install_mockery, mock_fetch, mock_packages, capfd,
pkg = spec.package
# Make sure install works even though there is no associated code.
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
out = capfd.readouterr()
assert "Installing dependency-install" in out[0]
@ -421,7 +422,7 @@ def test_nosource_bundle_pkg_install(
pkg = spec.package
# Make sure install works even though there is no associated code.
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
out = capfd.readouterr()
assert "Installing dependency-install" in out[0]
@ -435,7 +436,7 @@ def test_nosource_pkg_install_post_install(install_mockery, mock_fetch, mock_pac
pkg = spec.package
# Make sure both the install and post-install package methods work.
pkg.do_install()
PackageInstaller([pkg], explicit=True).install()
# Ensure the file created in the package's `install` method exists.
install_txt = os.path.join(spec.prefix, "install.txt")
@ -564,7 +565,7 @@ def test_unconcretized_install(install_mockery, mock_fetch, mock_packages):
pkg_cls = spack.repo.PATH.get_pkg_class(spec.name)
with pytest.raises(ValueError, match="must have a concrete spec"):
pkg_cls(spec).do_install()
PackageInstaller([pkg_cls(spec)], explicit=True).install()
with pytest.raises(ValueError, match="only patch concrete packages"):
pkg_cls(spec).do_patch()
@ -588,7 +589,7 @@ def test_empty_install_sanity_check_prefix(
"""Test empty install triggers sanity_check_prefix."""
spec = Spec("failing-empty-install").concretized()
with pytest.raises(spack.build_environment.ChildError, match="Nothing was installed"):
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
def test_install_from_binary_with_missing_patch_succeeds(
@ -624,10 +625,16 @@ def test_install_from_binary_with_missing_patch_succeeds(
# Source install: fails, we don't have the patch.
with pytest.raises(spack.error.SpecError, match="Couldn't find patch for package"):
s.package.do_install()
PackageInstaller([s.package], explicit=True).install()
# Binary install: succeeds, we don't need the patch.
spack.mirror.add(mirror)
s.package.do_install(package_cache_only=True, dependencies_cache_only=True, unsigned=True)
PackageInstaller(
[s.package],
explicit=True,
package_cache_only=True,
dependencies_cache_only=True,
unsigned=True,
).install()
assert temporary_store.db.query_local_by_spec_hash(s.dag_hash())

View File

@ -28,6 +28,7 @@
import spack.spec
import spack.store
import spack.util.lock as lk
from spack.installer import PackageInstaller
def _mock_repo(root, namespace):
@ -82,7 +83,7 @@ def create_installer(
concretized."""
_specs = [spack.spec.Spec(s).concretized() if isinstance(s, str) else s for s in specs]
_install_args = {} if install_args is None else install_args
return inst.PackageInstaller([spec.package for spec in _specs], _install_args)
return inst.PackageInstaller([spec.package for spec in _specs], **_install_args)
@pytest.mark.parametrize(
@ -140,7 +141,9 @@ def test_install_from_cache_errors(install_mockery):
with pytest.raises(
spack.error.InstallError, match="No binary found when cache-only was specified"
):
spec.package.do_install(package_cache_only=True, dependencies_cache_only=True)
PackageInstaller(
[spec.package], package_cache_only=True, dependencies_cache_only=True
).install()
assert not spec.package.installed_from_binary_cache
# Check when don't expect to install only from binary cache

View File

@ -18,6 +18,7 @@
import spack.package_prefs
import spack.repo
import spack.spec
from spack.installer import PackageInstaller
from spack.modules.common import UpstreamModuleIndex
from spack.spec import Spec
@ -180,7 +181,7 @@ def test_get_module_upstream():
def test_load_installed_package_not_in_repo(install_mockery, mock_fetch, monkeypatch):
"""Test that installed packages that have been removed are still loadable"""
spec = Spec("trivial-install-test-package").concretized()
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
spack.modules.module_types["tcl"](spec, "default", True).write()
def find_nothing(*args):

View File

@ -5,7 +5,7 @@
"""Test class methods on Package objects.
This doesn't include methods on package *instances* (like do_install(),
This doesn't include methods on package *instances* (like do_patch(),
etc.). Only methods like ``possible_dependencies()`` that deal with the
static DSL metadata for packages.
"""

View File

@ -30,6 +30,7 @@
import spack.util.gpg
import spack.util.url as url_util
from spack.fetch_strategy import URLFetchStrategy
from spack.installer import PackageInstaller
from spack.paths import mock_gpg_keys_path
from spack.relocate import (
macho_find_paths,
@ -50,7 +51,7 @@ def test_buildcache(mock_archive, tmp_path, monkeypatch, mutable_config):
# Install a test package
spec = Spec("trivial-install-test-package").concretized()
monkeypatch.setattr(spec.package, "fetcher", URLFetchStrategy(url=mock_archive.url))
spec.package.do_install()
PackageInstaller([spec.package], explicit=True).install()
pkghash = "/" + str(spec.dag_hash(7))
# Put some non-relocatable file in there

View File

@ -11,6 +11,7 @@
import spack.rewiring
import spack.store
from spack.installer import PackageInstaller
from spack.spec import Spec
from spack.test.relocate import text_in_bin
@ -27,8 +28,7 @@ def test_rewire_db(mock_fetch, install_mockery, transitive):
"""Tests basic rewiring without binary executables."""
spec = Spec("splice-t^splice-h~foo").concretized()
dep = Spec("splice-h+foo").concretized()
spec.package.do_install()
dep.package.do_install()
PackageInstaller([spec.package, dep.package], explicit=True).install()
spliced_spec = spec.splice(dep, transitive=transitive)
assert spec.dag_hash() != spliced_spec.dag_hash()
@ -57,8 +57,7 @@ def test_rewire_bin(mock_fetch, install_mockery, transitive):
"""Tests basic rewiring with binary executables."""
spec = Spec("quux").concretized()
dep = Spec("garply cflags=-g").concretized()
spec.package.do_install()
dep.package.do_install()
PackageInstaller([spec.package, dep.package], explicit=True).install()
spliced_spec = spec.splice(dep, transitive=transitive)
assert spec.dag_hash() != spliced_spec.dag_hash()
@ -86,8 +85,7 @@ def test_rewire_writes_new_metadata(mock_fetch, install_mockery):
Accuracy of metadata is left to other tests."""
spec = Spec("quux").concretized()
dep = Spec("garply cflags=-g").concretized()
spec.package.do_install()
dep.package.do_install()
PackageInstaller([spec.package, dep.package], explicit=True).install()
spliced_spec = spec.splice(dep, transitive=True)
spack.rewiring.rewire(spliced_spec)
@ -129,8 +127,7 @@ def test_uninstall_rewired_spec(mock_fetch, install_mockery, transitive):
"""Test that rewired packages can be uninstalled as normal."""
spec = Spec("quux").concretized()
dep = Spec("garply cflags=-g").concretized()
spec.package.do_install()
dep.package.do_install()
PackageInstaller([spec.package, dep.package], explicit=True).install()
spliced_spec = spec.splice(dep, transitive=transitive)
spack.rewiring.rewire(spliced_spec)
spliced_spec.package.do_uninstall()

View File

@ -6,6 +6,7 @@
import pytest
from spack.installer import PackageInstaller
from spack.spec import Spec
from spack.spec_list import SpecList
@ -200,8 +201,7 @@ def test_spec_list_exclude_with_abstract_hashes(self, mock_packages, install_moc
# Put mpich in the database so it can be referred to by hash.
mpich_1 = Spec("mpich+debug").concretized()
mpich_2 = Spec("mpich~debug").concretized()
mpich_1.package.do_install(fake=True)
mpich_2.package.do_install(fake=True)
PackageInstaller([mpich_1.package, mpich_2.package], explicit=True, fake=True).install()
# Create matrix and exclude +debug, which excludes the first mpich after its abstract hash
# is resolved.

View File

@ -9,6 +9,7 @@
from spack.directory_layout import DirectoryLayout
from spack.filesystem_view import SimpleFilesystemView, YamlFilesystemView
from spack.installer import PackageInstaller
from spack.spec import Spec
@ -17,7 +18,7 @@ def test_remove_extensions_ordered(install_mockery, mock_fetch, tmpdir):
layout = DirectoryLayout(view_dir)
view = YamlFilesystemView(view_dir, layout)
e2 = Spec("extension2").concretized()
e2.package.do_install()
PackageInstaller([e2.package], explicit=True).install()
view.add_specs(e2)
e1 = e2["extension1"]