summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2022-07-13 01:45:24 +0200
committerGitHub <noreply@github.com>2022-07-12 19:45:24 -0400
commit7f2b5e8e570cc1c6f783af80de083bde7c1ffc8c (patch)
treee60261f7ce32012081911a09ecf7712005af813e
parent6ceb274de035d42fc55822b2753a979355cd8af0 (diff)
downloadspack-7f2b5e8e570cc1c6f783af80de083bde7c1ffc8c.tar.gz
spack-7f2b5e8e570cc1c6f783af80de083bde7c1ffc8c.tar.bz2
spack-7f2b5e8e570cc1c6f783af80de083bde7c1ffc8c.tar.xz
spack-7f2b5e8e570cc1c6f783af80de083bde7c1ffc8c.zip
`spack.repo.get()` can only be called on concrete specs (#31411)
The goal of this PR is to make clearer where we need a package object in Spack as opposed to a package class. We currently instantiate a lot of package objects when we could make do with a class. We should use the class when we only need metadata, and we should only instantiate and us an instance of `PackageBase` at build time. Modifications: - [x] Remove the `spack.repo.get` convenience function (which was used in many places, and not really needed) - [x] Use `spack.repo.path.get_pkg_class` wherever possible - [x] Try to route most of the need for `spack.repo.path.get` through `Spec.package` - [x] Introduce a non-data descriptor, that can be used as a decorator, to have "class level properties" - [x] Refactor unit tests that had to be modified to reduce code duplication - [x] `Spec.package` and `Repo.get` now require a concrete spec as input - [x] Remove `RepoPath.all_packages` and `Repo.all_packages`
-rw-r--r--lib/spack/llnl/util/lang.py12
-rw-r--r--lib/spack/spack/audit.py68
-rw-r--r--lib/spack/spack/bootstrap.py6
-rw-r--r--lib/spack/spack/build_systems/python.py29
-rw-r--r--lib/spack/spack/build_systems/r.py32
-rw-r--r--lib/spack/spack/build_systems/racket.py9
-rw-r--r--lib/spack/spack/ci.py5
-rw-r--r--lib/spack/spack/cmd/blame.py4
-rw-r--r--lib/spack/spack/cmd/checksum.py4
-rw-r--r--lib/spack/spack/cmd/clean.py3
-rw-r--r--lib/spack/spack/cmd/dependents.py8
-rw-r--r--lib/spack/spack/cmd/dev_build.py6
-rw-r--r--lib/spack/spack/cmd/develop.py5
-rw-r--r--lib/spack/spack/cmd/extensions.py10
-rw-r--r--lib/spack/spack/cmd/external.py29
-rw-r--r--lib/spack/spack/cmd/info.py9
-rw-r--r--lib/spack/spack/cmd/list.py48
-rw-r--r--lib/spack/spack/cmd/mirror.py2
-rw-r--r--lib/spack/spack/cmd/patch.py3
-rw-r--r--lib/spack/spack/cmd/resource.py2
-rw-r--r--lib/spack/spack/cmd/restage.py3
-rw-r--r--lib/spack/spack/cmd/stage.py7
-rw-r--r--lib/spack/spack/cmd/url.py29
-rw-r--r--lib/spack/spack/cmd/versions.py5
-rw-r--r--lib/spack/spack/cray_manifest.py4
-rw-r--r--lib/spack/spack/detection/path.py4
-rw-r--r--lib/spack/spack/environment/environment.py9
-rw-r--r--lib/spack/spack/graph.py7
-rw-r--r--lib/spack/spack/hash_types.py10
-rw-r--r--lib/spack/spack/installer.py1
-rw-r--r--lib/spack/spack/mirror.py3
-rw-r--r--lib/spack/spack/package_base.py196
-rw-r--r--lib/spack/spack/package_prefs.py25
-rw-r--r--lib/spack/spack/patch.py14
-rw-r--r--lib/spack/spack/repo.py32
-rw-r--r--lib/spack/spack/solver/asp.py11
-rw-r--r--lib/spack/spack/spec.py30
-rw-r--r--lib/spack/spack/tag.py6
-rw-r--r--lib/spack/spack/test/build_systems.py382
-rw-r--r--lib/spack/spack/test/buildrequest.py5
-rw-r--r--lib/spack/spack/test/buildtask.py6
-rw-r--r--lib/spack/spack/test/cmd/checksum.py5
-rw-r--r--lib/spack/spack/test/cmd/dev_build.py15
-rw-r--r--lib/spack/spack/test/cmd/develop.py3
-rw-r--r--lib/spack/spack/test/cmd/env.py6
-rw-r--r--lib/spack/spack/test/cmd/external.py4
-rw-r--r--lib/spack/spack/test/cmd/location.py11
-rw-r--r--lib/spack/spack/test/cmd/mirror.py8
-rw-r--r--lib/spack/spack/test/cmd/tags.py5
-rw-r--r--lib/spack/spack/test/concretize.py22
-rw-r--r--lib/spack/spack/test/config.py9
-rw-r--r--lib/spack/spack/test/conftest.py3
-rw-r--r--lib/spack/spack/test/cvs_fetch.py22
-rw-r--r--lib/spack/spack/test/database.py6
-rw-r--r--lib/spack/spack/test/directory_layout.py19
-rw-r--r--lib/spack/spack/test/flag_handlers.py143
-rw-r--r--lib/spack/spack/test/git_fetch.py100
-rw-r--r--lib/spack/spack/test/hg_fetch.py20
-rw-r--r--lib/spack/spack/test/install.py131
-rw-r--r--lib/spack/spack/test/installer.py35
-rw-r--r--lib/spack/spack/test/mirror.py14
-rw-r--r--lib/spack/spack/test/modules/common.py41
-rw-r--r--lib/spack/spack/test/multimethod.py207
-rw-r--r--lib/spack/spack/test/package_class.py70
-rw-r--r--lib/spack/spack/test/package_sanity.py50
-rw-r--r--lib/spack/spack/test/packages.py292
-rw-r--r--lib/spack/spack/test/packaging.py5
-rw-r--r--lib/spack/spack/test/patch.py7
-rw-r--r--lib/spack/spack/test/repo.py19
-rw-r--r--lib/spack/spack/test/spec_dag.py10
-rw-r--r--lib/spack/spack/test/svn_fetch.py20
-rw-r--r--lib/spack/spack/test/url_fetch.py41
-rw-r--r--lib/spack/spack/test/util/package_hash.py19
-rw-r--r--lib/spack/spack/util/mock_package.py3
-rw-r--r--lib/spack/spack/variant.py12
-rw-r--r--lib/spack/spack/version.py2
-rw-r--r--var/spack/repos/builtin.mock/packages/multimethod/package.py14
-rw-r--r--var/spack/repos/builtin/packages/gcc/package.py5
-rw-r--r--var/spack/repos/builtin/packages/simmetrix-simmodsuite/package.py318
79 files changed, 1239 insertions, 1560 deletions
diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py
index b3236fa0e7..463310b7a2 100644
--- a/lib/spack/llnl/util/lang.py
+++ b/lib/spack/llnl/util/lang.py
@@ -1072,3 +1072,15 @@ class GroupedExceptionForwarder(object):
# Suppress any exception from being re-raised:
# https://docs.python.org/3/reference/datamodel.html#object.__exit__.
return True
+
+
+class classproperty(object):
+ """Non-data descriptor to evaluate a class-level property. The function that performs
+ the evaluation is injected at creation time and take an instance (could be None) and
+ an owner (i.e. the class that originated the instance)
+ """
+ def __init__(self, callback):
+ self.callback = callback
+
+ def __get__(self, instance, owner):
+ return self.callback(owner)
diff --git a/lib/spack/spack/audit.py b/lib/spack/spack/audit.py
index e090ff251f..713ccc6055 100644
--- a/lib/spack/spack/audit.py
+++ b/lib/spack/spack/audit.py
@@ -281,15 +281,15 @@ def _check_build_test_callbacks(pkgs, error_cls):
"""Ensure stand-alone test method is not included in build-time callbacks"""
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
- test_callbacks = pkg.build_time_test_callbacks
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
+ test_callbacks = pkg_cls.build_time_test_callbacks
if test_callbacks and 'test' in test_callbacks:
msg = ('{0} package contains "test" method in '
'build_time_test_callbacks')
instr = ('Remove "test" from: [{0}]'
.format(', '.join(test_callbacks)))
- errors.append(error_cls(msg.format(pkg.name), [instr]))
+ errors.append(error_cls(msg.format(pkg_name), [instr]))
return errors
@@ -304,8 +304,8 @@ def _check_patch_urls(pkgs, error_cls):
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
- for condition, patches in pkg.patches.items():
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
+ for condition, patches in pkg_cls.patches.items():
for patch in patches:
if not isinstance(patch, spack.patch.UrlPatch):
continue
@@ -317,7 +317,7 @@ def _check_patch_urls(pkgs, error_cls):
if not patch.url.endswith(full_index_arg):
errors.append(error_cls(
"patch URL in package {0} must end with {1}".format(
- pkg.name, full_index_arg,
+ pkg_cls.name, full_index_arg,
),
[patch.url],
))
@@ -331,21 +331,21 @@ def _linting_package_file(pkgs, error_cls):
"""
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
# Does the homepage have http, and if so, does https work?
- if pkg.homepage.startswith('http://'):
- https = re.sub("http", "https", pkg.homepage, 1)
+ if pkg_cls.homepage.startswith('http://'):
+ https = re.sub("http", "https", pkg_cls.homepage, 1)
try:
response = urlopen(https)
except Exception as e:
msg = 'Error with attempting https for "{0}": '
- errors.append(error_cls(msg.format(pkg.name), [str(e)]))
+ errors.append(error_cls(msg.format(pkg_cls.name), [str(e)]))
continue
if response.getcode() == 200:
msg = 'Package "{0}" uses http but has a valid https endpoint.'
- errors.append(msg.format(pkg.name))
+ errors.append(msg.format(pkg_cls.name))
return llnl.util.lang.dedupe(errors)
@@ -355,10 +355,10 @@ def _unknown_variants_in_directives(pkgs, error_cls):
"""Report unknown or wrong variants in directives for this package"""
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
# Check "conflicts" directive
- for conflict, triggers in pkg.conflicts.items():
+ for conflict, triggers in pkg_cls.conflicts.items():
for trigger, _ in triggers:
vrn = spack.spec.Spec(conflict)
try:
@@ -371,34 +371,34 @@ def _unknown_variants_in_directives(pkgs, error_cls):
# When os and target constraints can be created independently of
# the platform, TODO change this back to add an error.
errors.extend(_analyze_variants_in_directive(
- pkg, spack.spec.Spec(trigger),
+ pkg_cls, spack.spec.Spec(trigger),
directive='conflicts', error_cls=error_cls
))
errors.extend(_analyze_variants_in_directive(
- pkg, vrn, directive='conflicts', error_cls=error_cls
+ pkg_cls, vrn, directive='conflicts', error_cls=error_cls
))
# Check "depends_on" directive
- for _, triggers in pkg.dependencies.items():
+ for _, triggers in pkg_cls.dependencies.items():
triggers = list(triggers)
for trigger in list(triggers):
vrn = spack.spec.Spec(trigger)
errors.extend(_analyze_variants_in_directive(
- pkg, vrn, directive='depends_on', error_cls=error_cls
+ pkg_cls, vrn, directive='depends_on', error_cls=error_cls
))
# Check "patch" directive
- for _, triggers in pkg.provided.items():
+ for _, triggers in pkg_cls.provided.items():
triggers = [spack.spec.Spec(x) for x in triggers]
for vrn in triggers:
errors.extend(_analyze_variants_in_directive(
- pkg, vrn, directive='patch', error_cls=error_cls
+ pkg_cls, vrn, directive='patch', error_cls=error_cls
))
# Check "resource" directive
- for vrn in pkg.resources:
+ for vrn in pkg_cls.resources:
errors.extend(_analyze_variants_in_directive(
- pkg, vrn, directive='resource', error_cls=error_cls
+ pkg_cls, vrn, directive='resource', error_cls=error_cls
))
return llnl.util.lang.dedupe(errors)
@@ -409,15 +409,15 @@ def _unknown_variants_in_dependencies(pkgs, error_cls):
"""Report unknown dependencies and wrong variants for dependencies"""
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
filename = spack.repo.path.filename_for_package_name(pkg_name)
- for dependency_name, dependency_data in pkg.dependencies.items():
+ for dependency_name, dependency_data in pkg_cls.dependencies.items():
# No need to analyze virtual packages
if spack.repo.path.is_virtual(dependency_name):
continue
try:
- dependency_pkg = spack.repo.get(dependency_name)
+ dependency_pkg_cls = spack.repo.path.get_pkg_class(dependency_name)
except spack.repo.UnknownPackageError:
# This dependency is completely missing, so report
# and continue the analysis
@@ -433,8 +433,8 @@ def _unknown_variants_in_dependencies(pkgs, error_cls):
dependency_variants = dependency_edge.spec.variants
for name, value in dependency_variants.items():
try:
- v, _ = dependency_pkg.variants[name]
- v.validate_or_raise(value, pkg=dependency_pkg)
+ v, _ = dependency_pkg_cls.variants[name]
+ v.validate_or_raise(value, pkg_cls=dependency_pkg_cls)
except Exception as e:
summary = (pkg_name + ": wrong variant used for a "
"dependency in a 'depends_on' directive")
@@ -456,10 +456,10 @@ def _version_constraints_are_satisfiable_by_some_version_in_repo(pkgs, error_cls
"""Report if version constraints used in directives are not satisfiable"""
errors = []
for pkg_name in pkgs:
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
filename = spack.repo.path.filename_for_package_name(pkg_name)
dependencies_to_check = []
- for dependency_name, dependency_data in pkg.dependencies.items():
+ for dependency_name, dependency_data in pkg_cls.dependencies.items():
# Skip virtual dependencies for the time being, check on
# their versions can be added later
if spack.repo.path.is_virtual(dependency_name):
@@ -470,19 +470,19 @@ def _version_constraints_are_satisfiable_by_some_version_in_repo(pkgs, error_cls
)
for s in dependencies_to_check:
- dependency_pkg = None
+ dependency_pkg_cls = None
try:
- dependency_pkg = spack.repo.get(s.name)
+ dependency_pkg_cls = spack.repo.path.get_pkg_class(s.name)
assert any(
- v.satisfies(s.versions) for v in list(dependency_pkg.versions)
+ v.satisfies(s.versions) for v in list(dependency_pkg_cls.versions)
)
except Exception:
summary = ("{0}: dependency on {1} cannot be satisfied "
"by known versions of {1.name}").format(pkg_name, s)
details = ['happening in ' + filename]
- if dependency_pkg is not None:
+ if dependency_pkg_cls is not None:
details.append('known versions of {0.name} are {1}'.format(
- s, ', '.join([str(x) for x in dependency_pkg.versions])
+ s, ', '.join([str(x) for x in dependency_pkg_cls.versions])
))
errors.append(error_cls(summary=summary, details=details))
@@ -500,7 +500,7 @@ def _analyze_variants_in_directive(pkg, constraint, directive, error_cls):
for name, v in constraint.variants.items():
try:
variant, _ = pkg.variants[name]
- variant.validate_or_raise(v, pkg=pkg)
+ variant.validate_or_raise(v, pkg_cls=pkg)
except variant_exceptions as e:
summary = pkg.name + ': wrong variant in "{0}" directive'
summary = summary.format(directive)
diff --git a/lib/spack/spack/bootstrap.py b/lib/spack/spack/bootstrap.py
index 1e4b9e778d..b4b705e57c 100644
--- a/lib/spack/spack/bootstrap.py
+++ b/lib/spack/spack/bootstrap.py
@@ -652,10 +652,10 @@ def _add_compilers_if_missing():
def _add_externals_if_missing():
search_list = [
# clingo
- spack.repo.path.get('cmake'),
- spack.repo.path.get('bison'),
+ spack.repo.path.get_pkg_class('cmake'),
+ spack.repo.path.get_pkg_class('bison'),
# GnuPG
- spack.repo.path.get('gawk')
+ spack.repo.path.get_pkg_class('gawk')
]
detected_packages = spack.detection.by_executable(search_list)
spack.detection.update_configuration(detected_packages, scope='bootstrap')
diff --git a/lib/spack/spack/build_systems/python.py b/lib/spack/spack/build_systems/python.py
index 3eec9d5d3b..4e109b628d 100644
--- a/lib/spack/spack/build_systems/python.py
+++ b/lib/spack/spack/build_systems/python.py
@@ -19,7 +19,7 @@ from llnl.util.filesystem import (
same_path,
working_dir,
)
-from llnl.util.lang import match_predicate
+from llnl.util.lang import classproperty, match_predicate
from spack.directives import depends_on, extends
from spack.error import NoHeadersError, NoLibrariesError
@@ -77,24 +77,21 @@ class PythonPackage(PackageBase):
'--no-index',
]
- @property
- def homepage(self):
- if self.pypi:
- name = self.pypi.split('/')[0]
+ @classproperty
+ def homepage(cls):
+ if cls.pypi:
+ name = cls.pypi.split('/')[0]
return 'https://pypi.org/project/' + name + '/'
- @property
- def url(self):
- if self.pypi:
- return (
- 'https://files.pythonhosted.org/packages/source/'
- + self.pypi[0] + '/' + self.pypi
- )
+ @classproperty
+ def url(cls):
+ if cls.pypi:
+ return 'https://files.pythonhosted.org/packages/source/' + cls.pypi[0] + '/' + cls.pypi
- @property
- def list_url(self):
- if self.pypi:
- name = self.pypi.split('/')[0]
+ @classproperty
+ def list_url(cls):
+ if cls.pypi:
+ name = cls.pypi.split('/')[0]
return 'https://pypi.org/simple/' + name + '/'
@property
diff --git a/lib/spack/spack/build_systems/r.py b/lib/spack/spack/build_systems/r.py
index b1df2f594d..9a94152b82 100644
--- a/lib/spack/spack/build_systems/r.py
+++ b/lib/spack/spack/build_systems/r.py
@@ -2,11 +2,11 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-
import inspect
from typing import Optional
+import llnl.util.lang as lang
+
from spack.directives import extends
from spack.package_base import PackageBase, run_after
@@ -42,27 +42,27 @@ class RPackage(PackageBase):
extends('r')
- @property
- def homepage(self):
- if self.cran:
- return 'https://cloud.r-project.org/package=' + self.cran
- elif self.bioc:
- return 'https://bioconductor.org/packages/' + self.bioc
+ @lang.classproperty
+ def homepage(cls):
+ if cls.cran:
+ return 'https://cloud.r-project.org/package=' + cls.cran
+ elif cls.bioc:
+ return 'https://bioconductor.org/packages/' + cls.bioc
- @property
- def url(self):
- if self.cran:
+ @lang.classproperty
+ def url(cls):
+ if cls.cran:
return (
'https://cloud.r-project.org/src/contrib/'
- + self.cran + '_' + str(list(self.versions)[0]) + '.tar.gz'
+ + cls.cran + '_' + str(list(cls.versions)[0]) + '.tar.gz'
)
- @property
- def list_url(self):
- if self.cran:
+ @lang.classproperty
+ def list_url(cls):
+ if cls.cran:
return (
'https://cloud.r-project.org/src/contrib/Archive/'
- + self.cran + '/'
+ + cls.cran + '/'
)
@property
diff --git a/lib/spack/spack/build_systems/racket.py b/lib/spack/spack/build_systems/racket.py
index 1c9e8e84d8..b2419f04e6 100644
--- a/lib/spack/spack/build_systems/racket.py
+++ b/lib/spack/spack/build_systems/racket.py
@@ -5,6 +5,7 @@
import os
from typing import Optional
+import llnl.util.lang as lang
import llnl.util.tty as tty
from llnl.util.filesystem import working_dir
@@ -41,10 +42,10 @@ class RacketPackage(PackageBase):
name = None # type: Optional[str]
parallel = True
- @property
- def homepage(self):
- if self.pkgs:
- return 'https://pkgs.racket-lang.org/package/{0}'.format(self.name)
+ @lang.classproperty
+ def homepage(cls):
+ if cls.pkgs:
+ return 'https://pkgs.racket-lang.org/package/{0}'.format(cls.name)
@property
def build_directory(self):
diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index d600e69c42..8467645fb5 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -1628,8 +1628,9 @@ def copy_stage_logs_to_artifacts(job_spec, job_log_dir):
job_log_dir (str): Path into which build log should be copied
"""
try:
- job_pkg = spack.repo.get(job_spec)
- tty.debug('job package: {0}'.format(job_pkg))
+ pkg_cls = spack.repo.path.get_pkg_class(job_spec.name)
+ job_pkg = pkg_cls(job_spec)
+ tty.debug('job package: {0.fullname}'.format(job_pkg))
stage_dir = job_pkg.stage.path
tty.debug('stage dir: {0}'.format(stage_dir))
build_out_src = os.path.join(stage_dir, 'spack-build-out.txt')
diff --git a/lib/spack/spack/cmd/blame.py b/lib/spack/spack/cmd/blame.py
index 06ceaf2e34..9f32be5790 100644
--- a/lib/spack/spack/cmd/blame.py
+++ b/lib/spack/spack/cmd/blame.py
@@ -99,8 +99,8 @@ def blame(parser, args):
blame_file = path
if not blame_file:
- pkg = spack.repo.get(args.package_or_file)
- blame_file = pkg.module.__file__.rstrip('c') # .pyc -> .py
+ pkg_cls = spack.repo.path.get_pkg_class(args.package_or_file)
+ blame_file = pkg_cls.module.__file__.rstrip('c') # .pyc -> .py
# get git blame for the package
with working_dir(spack.paths.prefix):
diff --git a/lib/spack/spack/cmd/checksum.py b/lib/spack/spack/cmd/checksum.py
index 37c06ac7bb..89509cca29 100644
--- a/lib/spack/spack/cmd/checksum.py
+++ b/lib/spack/spack/cmd/checksum.py
@@ -12,6 +12,7 @@ import llnl.util.tty as tty
import spack.cmd
import spack.cmd.common.arguments as arguments
import spack.repo
+import spack.spec
import spack.stage
import spack.util.crypto
from spack.package_base import preferred_version
@@ -54,7 +55,8 @@ def checksum(parser, args):
tty.die("`spack checksum` accepts package names, not URLs.")
# Get the package we're going to generate checksums for
- pkg = spack.repo.get(args.package)
+ pkg_cls = spack.repo.path.get_pkg_class(args.package)
+ pkg = pkg_cls(spack.spec.Spec(args.package))
url_dict = {}
versions = args.versions
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index 6948aa3177..71fee4f3ff 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -85,8 +85,7 @@ def clean(parser, args):
for spec in specs:
msg = 'Cleaning build stage [{0}]'
tty.msg(msg.format(spec.short_spec))
- package = spack.repo.get(spec)
- package.do_clean()
+ spec.package.do_clean()
if args.stage:
tty.msg('Removing all temporary build stages')
diff --git a/lib/spack/spack/cmd/dependents.py b/lib/spack/spack/cmd/dependents.py
index 2148a922f6..cbaac206dc 100644
--- a/lib/spack/spack/cmd/dependents.py
+++ b/lib/spack/spack/cmd/dependents.py
@@ -39,9 +39,9 @@ def inverted_dependencies():
actual dependents.
"""
dag = {}
- for pkg in spack.repo.path.all_packages():
- dag.setdefault(pkg.name, set())
- for dep in pkg.dependencies:
+ for pkg_cls in spack.repo.path.all_package_classes():
+ dag.setdefault(pkg_cls.name, set())
+ for dep in pkg_cls.dependencies:
deps = [dep]
# expand virtuals if necessary
@@ -49,7 +49,7 @@ def inverted_dependencies():
deps += [s.name for s in spack.repo.path.providers_for(dep)]
for d in deps:
- dag.setdefault(d, set()).add(pkg.name)
+ dag.setdefault(d, set()).add(pkg_cls.name)
return dag
diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py
index bb8c79f048..50fd0d0cee 100644
--- a/lib/spack/spack/cmd/dev_build.py
+++ b/lib/spack/spack/cmd/dev_build.py
@@ -87,9 +87,7 @@ def dev_build(self, args):
# Forces the build to run out of the source directory.
spec.constrain('dev_path=%s' % source_path)
-
spec.concretize()
- package = spack.repo.get(spec)
if spec.installed:
tty.error("Already installed in %s" % spec.prefix)
@@ -109,7 +107,7 @@ def dev_build(self, args):
elif args.test == 'root':
tests = [spec.name for spec in specs]
- package.do_install(
+ spec.package.do_install(
tests=tests,
make_jobs=args.jobs,
keep_prefix=args.keep_prefix,
@@ -122,5 +120,5 @@ def dev_build(self, args):
# drop into the build environment of the package?
if args.shell is not None:
- spack.build_environment.setup_package(package, dirty=False)
+ spack.build_environment.setup_package(spec.package, dirty=False)
os.execvp(args.shell, [args.shell])
diff --git a/lib/spack/spack/cmd/develop.py b/lib/spack/spack/cmd/develop.py
index 88e53227fb..736bbc361d 100644
--- a/lib/spack/spack/cmd/develop.py
+++ b/lib/spack/spack/cmd/develop.py
@@ -54,8 +54,9 @@ def develop(parser, args):
tty.msg(msg)
continue
- stage = spack.spec.Spec(entry['spec']).package.stage
- stage.steal_source(abspath)
+ spec = spack.spec.Spec(entry['spec'])
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ pkg_cls(spec).stage.steal_source(abspath)
if not env.dev_specs:
tty.warn("No develop specs to download")
diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
index 0588326005..059b76e411 100644
--- a/lib/spack/spack/cmd/extensions.py
+++ b/lib/spack/spack/cmd/extensions.py
@@ -52,8 +52,8 @@ def extensions(parser, args):
extendable_pkgs = []
for name in spack.repo.all_package_names():
- pkg = spack.repo.get(name)
- if pkg.extendable:
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ if pkg_cls.extendable:
extendable_pkgs.append(name)
colify(extendable_pkgs, indent=4)
@@ -64,13 +64,13 @@ def extensions(parser, args):
if len(spec) > 1:
tty.die("Can only list extensions for one package.")
- if not spec[0].package.extendable:
- tty.die("%s is not an extendable package." % spec[0].name)
-
env = ev.active_environment()
spec = cmd.disambiguate_spec(spec[0], env)
if not spec.package.extendable:
+ tty.die("%s is not an extendable package." % spec[0].name)
+
+ if not spec.package.extendable:
tty.die("%s does not have extensions." % spec.short_spec)
if args.show in ("packages", "all"):
diff --git a/lib/spack/spack/cmd/external.py b/lib/spack/spack/cmd/external.py
index 20f4744a1e..768ec2ebd2 100644
--- a/lib/spack/spack/cmd/external.py
+++ b/lib/spack/spack/cmd/external.py
@@ -119,34 +119,37 @@ def external_find(args):
args.tags = []
# Construct the list of possible packages to be detected
- packages_to_check = []
+ pkg_cls_to_check = []
# Add the packages that have been required explicitly
if args.packages:
- packages_to_check = list(spack.repo.get(pkg) for pkg in args.packages)
+ pkg_cls_to_check = [
+ spack.repo.path.get_pkg_class(pkg) for pkg in args.packages
+ ]
if args.tags:
allowed = set(spack.repo.path.packages_with_tags(*args.tags))
- packages_to_check = [x for x in packages_to_check if x in allowed]
+ pkg_cls_to_check = [x for x in pkg_cls_to_check if x.name in allowed]
- if args.tags and not packages_to_check:
+ if args.tags and not pkg_cls_to_check:
# If we arrived here we didn't have any explicit package passed
# as argument, which means to search all packages.
# Since tags are cached it's much faster to construct what we need
# to search directly, rather than filtering after the fact
- packages_to_check = [
- spack.repo.get(pkg) for tag in args.tags for pkg in
- spack.repo.path.packages_with_tags(tag)
+ pkg_cls_to_check = [
+ spack.repo.path.get_pkg_class(pkg_name)
+ for tag in args.tags
+ for pkg_name in spack.repo.path.packages_with_tags(tag)
]
- packages_to_check = list(set(packages_to_check))
+ pkg_cls_to_check = list(set(pkg_cls_to_check))
# If the list of packages is empty, search for every possible package
- if not args.tags and not packages_to_check:
- packages_to_check = list(spack.repo.path.all_packages())
+ if not args.tags and not pkg_cls_to_check:
+ pkg_cls_to_check = list(spack.repo.path.all_package_classes())
detected_packages = spack.detection.by_executable(
- packages_to_check, path_hints=args.path)
+ pkg_cls_to_check, path_hints=args.path)
detected_packages.update(spack.detection.by_library(
- packages_to_check, path_hints=args.path))
+ pkg_cls_to_check, path_hints=args.path))
new_entries = spack.detection.update_configuration(
detected_packages, scope=args.scope, buildable=not args.not_buildable
@@ -217,7 +220,7 @@ def _collect_and_consume_cray_manifest_files(
def external_list(args):
# Trigger a read of all packages, might take a long time.
- list(spack.repo.path.all_packages())
+ list(spack.repo.path.all_package_classes())
# Print all the detectable packages
tty.msg("Detectable packages per repository")
for namespace, pkgs in sorted(spack.package_base.detectable_packages.items()):
diff --git a/lib/spack/spack/cmd/info.py b/lib/spack/spack/cmd/info.py
index 31ea53f384..0f0b26c334 100644
--- a/lib/spack/spack/cmd/info.py
+++ b/lib/spack/spack/cmd/info.py
@@ -292,10 +292,9 @@ def print_tests(pkg):
v_specs = [spack.spec.Spec(v_name) for v_name in v_names]
for v_spec in v_specs:
try:
- pkg = v_spec.package
- pkg_cls = pkg if inspect.isclass(pkg) else pkg.__class__
+ pkg_cls = spack.repo.path.get_pkg_class(v_spec.name)
if has_test_method(pkg_cls):
- names.append('{0}.test'.format(pkg.name.lower()))
+ names.append('{0}.test'.format(pkg_cls.name.lower()))
except spack.repo.UnknownPackageError:
pass
@@ -386,7 +385,9 @@ def print_virtuals(pkg):
def info(parser, args):
- pkg = spack.repo.get(args.package)
+ spec = spack.spec.Spec(args.package)
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ pkg = pkg_cls(spec)
# Output core package information
header = section_title(
diff --git a/lib/spack/spack/cmd/list.py b/lib/spack/spack/cmd/list.py
index 7893727c23..8e91831bd7 100644
--- a/lib/spack/spack/cmd/list.py
+++ b/lib/spack/spack/cmd/list.py
@@ -84,9 +84,9 @@ def filter_by_name(pkgs, args):
if f.match(p):
return True
- pkg = spack.repo.get(p)
- if pkg.__doc__:
- return f.match(pkg.__doc__)
+ pkg_cls = spack.repo.path.get_pkg_class(p)
+ if pkg_cls.__doc__:
+ return f.match(pkg_cls.__doc__)
return False
else:
def match(p, f):
@@ -133,7 +133,7 @@ def get_dependencies(pkg):
@formatter
def version_json(pkg_names, out):
"""Print all packages with their latest versions."""
- pkgs = [spack.repo.get(name) for name in pkg_names]
+ pkg_classes = [spack.repo.path.get_pkg_class(name) for name in pkg_names]
out.write('[\n')
@@ -147,14 +147,14 @@ def version_json(pkg_names, out):
' "maintainers": {5},\n'
' "dependencies": {6}'
'}}'.format(
- pkg.name,
- VersionList(pkg.versions).preferred(),
- json.dumps([str(v) for v in reversed(sorted(pkg.versions))]),
- pkg.homepage,
- github_url(pkg),
- json.dumps(pkg.maintainers),
- json.dumps(get_dependencies(pkg))
- ) for pkg in pkgs
+ pkg_cls.name,
+ VersionList(pkg_cls.versions).preferred(),
+ json.dumps([str(v) for v in reversed(sorted(pkg_cls.versions))]),
+ pkg_cls.homepage,
+ github_url(pkg_cls),
+ json.dumps(pkg_cls.maintainers),
+ json.dumps(get_dependencies(pkg_cls))
+ ) for pkg_cls in pkg_classes
])
out.write(pkg_latest)
# important: no trailing comma in JSON arrays
@@ -172,7 +172,7 @@ def html(pkg_names, out):
"""
# Read in all packages
- pkgs = [spack.repo.get(name) for name in pkg_names]
+ pkg_classes = [spack.repo.path.get_pkg_class(name) for name in pkg_names]
# Start at 2 because the title of the page from Sphinx is id1.
span_id = 2
@@ -189,7 +189,7 @@ def html(pkg_names, out):
# Start with the number of packages, skipping the title and intro
# blurb, which we maintain in the RST file.
out.write('<p>\n')
- out.write('Spack currently has %d mainline packages:\n' % len(pkgs))
+ out.write('Spack currently has %d mainline packages:\n' % len(pkg_classes))
out.write('</p>\n')
# Table of links to all packages
@@ -209,9 +209,9 @@ def html(pkg_names, out):
out.write('<hr class="docutils"/>\n')
# Output some text for each package.
- for pkg in pkgs:
- out.write('<div class="section" id="%s">\n' % pkg.name)
- head(2, span_id, pkg.name)
+ for pkg_cls in pkg_classes:
+ out.write('<div class="section" id="%s">\n' % pkg_cls.name)
+ head(2, span_id, pkg_cls.name)
span_id += 1
out.write('<dl class="docutils">\n')
@@ -219,10 +219,10 @@ def html(pkg_names, out):
out.write('<dt>Homepage:</dt>\n')
out.write('<dd><ul class="first last simple">\n')
- if pkg.homepage:
+ if pkg_cls.homepage:
out.write(('<li>'
'<a class="reference external" href="%s">%s</a>'
- '</li>\n') % (pkg.homepage, escape(pkg.homepage, True)))
+ '</li>\n') % (pkg_cls.homepage, escape(pkg_cls.homepage, True)))
else:
out.write('No homepage\n')
out.write('</ul></dd>\n')
@@ -231,19 +231,19 @@ def html(pkg_names, out):
out.write('<dd><ul class="first last simple">\n')
out.write(('<li>'
'<a class="reference external" href="%s">%s/package.py</a>'
- '</li>\n') % (github_url(pkg), pkg.name))
+ '</li>\n') % (github_url(pkg_cls), pkg_cls.name))
out.write('</ul></dd>\n')
- if pkg.versions:
+ if pkg_cls.versions:
out.write('<dt>Versions:</dt>\n')
out.write('<dd>\n')
out.write(', '.join(
- str(v) for v in reversed(sorted(pkg.versions))))
+ str(v) for v in reversed(sorted(pkg_cls.versions))))
out.write('\n')
out.write('</dd>\n')
for deptype in spack.dependency.all_deptypes:
- deps = pkg.dependencies_of_type(deptype)
+ deps = pkg_cls.dependencies_of_type(deptype)
if deps:
out.write('<dt>%s Dependencies:</dt>\n' % deptype.capitalize())
out.write('<dd>\n')
@@ -256,7 +256,7 @@ def html(pkg_names, out):
out.write('<dt>Description:</dt>\n')
out.write('<dd>\n')
- out.write(escape(pkg.format_doc(indent=2), True))
+ out.write(escape(pkg_cls.format_doc(indent=2), True))
out.write('\n')
out.write('</dd>\n')
out.write('</dl>\n')
diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py
index 1faa13030a..e043702bf3 100644
--- a/lib/spack/spack/cmd/mirror.py
+++ b/lib/spack/spack/cmd/mirror.py
@@ -221,7 +221,7 @@ def _read_specs_from_file(filename):
for i, string in enumerate(stream):
try:
s = Spec(string)
- s.package
+ spack.repo.path.get_pkg_class(s.name)
specs.append(s)
except SpackError as e:
tty.debug(e)
diff --git a/lib/spack/spack/cmd/patch.py b/lib/spack/spack/cmd/patch.py
index 16ea69f7c9..c9031a62c6 100644
--- a/lib/spack/spack/cmd/patch.py
+++ b/lib/spack/spack/cmd/patch.py
@@ -31,5 +31,4 @@ def patch(parser, args):
specs = spack.cmd.parse_specs(args.specs, concretize=True)
for spec in specs:
- package = spack.repo.get(spec)
- package.do_patch()
+ spec.package.do_patch()
diff --git a/lib/spack/spack/cmd/resource.py b/lib/spack/spack/cmd/resource.py
index 1853b97f09..82a2d2c687 100644
--- a/lib/spack/spack/cmd/resource.py
+++ b/lib/spack/spack/cmd/resource.py
@@ -50,7 +50,7 @@ def _show_patch(sha256):
owner = rec['owner']
if 'relative_path' in rec:
- pkg_dir = spack.repo.get(owner).package_dir
+ pkg_dir = spack.repo.path.get_pkg_class(owner).package_dir
path = os.path.join(pkg_dir, rec['relative_path'])
print(" path: %s" % path)
else:
diff --git a/lib/spack/spack/cmd/restage.py b/lib/spack/spack/cmd/restage.py
index 53679d2195..278d6ca217 100644
--- a/lib/spack/spack/cmd/restage.py
+++ b/lib/spack/spack/cmd/restage.py
@@ -24,5 +24,4 @@ def restage(parser, args):
specs = spack.cmd.parse_specs(args.specs, concretize=True)
for spec in specs:
- package = spack.repo.get(spec)
- package.do_restage()
+ spec.package.do_restage()
diff --git a/lib/spack/spack/cmd/stage.py b/lib/spack/spack/cmd/stage.py
index 56f9a7e32c..8e039c832a 100644
--- a/lib/spack/spack/cmd/stage.py
+++ b/lib/spack/spack/cmd/stage.py
@@ -58,8 +58,7 @@ def stage(parser, args):
for spec in specs:
spec = spack.cmd.matching_spec_from_env(spec)
- package = spack.repo.get(spec)
if custom_path:
- package.path = custom_path
- package.do_stage()
- tty.msg("Staged {0} in {1}".format(package.name, package.stage.path))
+ spec.package.path = custom_path
+ spec.package.do_stage()
+ tty.msg("Staged {0} in {1}".format(spec.package.name, spec.package.stage.path))
diff --git a/lib/spack/spack/cmd/url.py b/lib/spack/spack/cmd/url.py
index 97fa300a3d..be24d86ffc 100644
--- a/lib/spack/spack/cmd/url.py
+++ b/lib/spack/spack/cmd/url.py
@@ -14,6 +14,7 @@ from llnl.util import tty
import spack.fetch_strategy as fs
import spack.repo
+import spack.spec
import spack.util.crypto as crypto
from spack.url import (
UndetectableNameError,
@@ -147,13 +148,13 @@ def url_list(args):
urls = set()
# Gather set of URLs from all packages
- for pkg in spack.repo.path.all_packages():
- url = getattr(pkg, 'url', None)
- urls = url_list_parsing(args, urls, url, pkg)
+ for pkg_cls in spack.repo.path.all_package_classes():
+ url = getattr(pkg_cls, 'url', None)
+ urls = url_list_parsing(args, urls, url, pkg_cls)
- for params in pkg.versions.values():
+ for params in pkg_cls.versions.values():
url = params.get('url', None)
- urls = url_list_parsing(args, urls, url, pkg)
+ urls = url_list_parsing(args, urls, url, pkg_cls)
# Print URLs
for url in sorted(urls):
@@ -184,8 +185,9 @@ def url_summary(args):
tty.msg('Generating a summary of URL parsing in Spack...')
# Loop through all packages
- for pkg in spack.repo.path.all_packages():
+ for pkg_cls in spack.repo.path.all_package_classes():
urls = set()
+ pkg = pkg_cls(spack.spec.Spec(pkg_cls.name))
url = getattr(pkg, 'url', None)
if url:
@@ -318,19 +320,20 @@ def url_stats(args):
version_stats = UrlStats()
resource_stats = UrlStats()
- for pkg in spack.repo.path.all_packages():
+ for pkg_cls in spack.repo.path.all_package_classes():
npkgs += 1
- for v in pkg.versions:
+ for v in pkg_cls.versions:
try:
+ pkg = pkg_cls(spack.spec.Spec(pkg_cls.name))
fetcher = fs.for_package_version(pkg, v)
except (fs.InvalidArgsError, fs.FetcherConflict):
continue
- version_stats.add(pkg.name, fetcher)
+ version_stats.add(pkg_cls.name, fetcher)
- for _, resources in pkg.resources.items():
+ for _, resources in pkg_cls.resources.items():
for resource in resources:
- resource_stats.add(pkg.name, resource.fetcher)
+ resource_stats.add(pkg_cls.name, resource.fetcher)
# print a nice summary table
tty.msg("URL stats for %d packages:" % npkgs)
@@ -390,8 +393,8 @@ def url_stats(args):
tty.msg("Found %d issues." % total_issues)
for issue_type, pkgs in issues.items():
tty.msg("Package URLs with %s" % issue_type)
- for pkg, pkg_issues in pkgs.items():
- color.cprint(" @*C{%s}" % pkg)
+ for pkg_cls, pkg_issues in pkgs.items():
+ color.cprint(" @*C{%s}" % pkg_cls)
for issue in pkg_issues:
print(" %s" % issue)
diff --git a/lib/spack/spack/cmd/versions.py b/lib/spack/spack/cmd/versions.py
index 891ea3f965..10df443baa 100644
--- a/lib/spack/spack/cmd/versions.py
+++ b/lib/spack/spack/cmd/versions.py
@@ -12,6 +12,7 @@ from llnl.util.tty.colify import colify
import spack.cmd.common.arguments as arguments
import spack.repo
+import spack.spec
from spack.version import infinity_versions, ver
description = "list available versions of a package"
@@ -39,7 +40,9 @@ def setup_parser(subparser):
def versions(parser, args):
- pkg = spack.repo.get(args.package)
+ spec = spack.spec.Spec(args.package)
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ pkg = pkg_cls(spec)
safe_versions = pkg.versions
diff --git a/lib/spack/spack/cray_manifest.py b/lib/spack/spack/cray_manifest.py
index 62da9bc868..fa9c061d0c 100644
--- a/lib/spack/spack/cray_manifest.py
+++ b/lib/spack/spack/cray_manifest.py
@@ -86,13 +86,13 @@ def spec_from_entry(entry):
arch=arch_str
)
- package = spack.repo.get(entry['name'])
+ pkg_cls = spack.repo.path.get_pkg_class(entry['name'])
if 'parameters' in entry:
variant_strs = list()
for name, value in entry['parameters'].items():
# TODO: also ensure that the variant value is valid?
- if not (name in package.variants):
+ if not (name in pkg_cls.variants):
tty.debug("Omitting variant {0} for entry {1}/{2}"
.format(name, entry['name'], entry['hash'][:7]))
continue
diff --git a/lib/spack/spack/detection/path.py b/lib/spack/spack/detection/path.py
index b56644a6b4..c344b24cd7 100644
--- a/lib/spack/spack/detection/path.py
+++ b/lib/spack/spack/detection/path.py
@@ -220,7 +220,7 @@ def by_executable(packages_to_check, path_hints=None):
searching by path.
Args:
- packages_to_check (list): list of packages to be detected
+ packages_to_check (list): list of package classes to be detected
path_hints (list): list of paths to be searched. If None the list will be
constructed based on the PATH environment variable.
"""
@@ -228,7 +228,7 @@ def by_executable(packages_to_check, path_hints=None):
exe_pattern_to_pkgs = collections.defaultdict(list)
for pkg in packages_to_check:
if hasattr(pkg, 'executables'):
- for exe in pkg.platform_executables:
+ for exe in pkg.platform_executables():
exe_pattern_to_pkgs[exe].append(pkg)
# Add Windows specific, package related paths to the search paths
path_hints.extend(compute_windows_program_path_for_package(pkg))
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index 1c16c708b3..ad900f53ff 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -1113,8 +1113,13 @@ class Environment(object):
# "steal" the source code via staging API
abspath = os.path.normpath(os.path.join(self.path, path))
- stage = spec.package.stage
- stage.steal_source(abspath)
+ # Stage, at the moment, requires a concrete Spec, since it needs the
+ # dag_hash for the stage dir name. Below though we ask for a stage
+ # to be created, to copy it afterwards somewhere else. It would be
+ # better if we can create the `source_path` directly into its final
+ # destination.
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ pkg_cls(spec).stage.steal_source(abspath)
# If it wasn't already in the list, append it
self.dev_specs[spec.name] = {'path': path, 'spec': str(spec)}
diff --git a/lib/spack/spack/graph.py b/lib/spack/spack/graph.py
index d1e95c6f52..2c0a07f17c 100644
--- a/lib/spack/spack/graph.py
+++ b/lib/spack/spack/graph.py
@@ -535,9 +535,10 @@ def graph_dot(specs, deptype='all', static=False, out=None):
deptype = spack.dependency.canonical_deptype(deptype)
def static_graph(spec, deptype):
- pkg = spec.package
- possible = pkg.possible_dependencies(
- expand_virtuals=True, deptype=deptype)
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ possible = pkg_cls.possible_dependencies(
+ expand_virtuals=True, deptype=deptype
+ )
nodes = set() # elements are (node name, node label)
edges = set() # elements are (src key, dest key)
diff --git a/lib/spack/spack/hash_types.py b/lib/spack/spack/hash_types.py
index abe8a0b282..d9065148f2 100644
--- a/lib/spack/spack/hash_types.py
+++ b/lib/spack/spack/hash_types.py
@@ -2,10 +2,10 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
"""Definitions that control how Spack creates Spec hashes."""
import spack.dependency as dp
+import spack.repo
hashes = []
@@ -51,10 +51,16 @@ process_hash = SpecHashDescriptor(
)
+def _content_hash_override(spec):
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ pkg = pkg_cls(spec)
+ return pkg.content_hash()
+
+
#: Package hash used as part of dag hash
package_hash = SpecHashDescriptor(
deptype=(), package_hash=True, name='package_hash',
- override=lambda s: s.package.content_hash())
+ override=_content_hash_override)
# Deprecated hash types, no longer used, but needed to understand old serialized
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index d659c5b4b8..af34388eb4 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -232,6 +232,7 @@ def _packages_needed_to_bootstrap_compiler(compiler, architecture, pkgs):
)
packages = [(s.package, False) for
s in dep.traverse(order='post', root=False)]
+
packages.append((dep.package, True))
return packages
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index 0085d920b8..bdafb70e25 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -391,7 +391,8 @@ def mirror_archive_paths(fetcher, per_package_ref, spec=None):
storage path of the resource associated with the specified ``fetcher``."""
ext = None
if spec:
- versions = spec.package.versions.get(spec.package.version, {})
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ versions = pkg_cls.versions.get(spec.version, {})
ext = versions.get('extension', None)
# If the spec does not explicitly specify an extension (the default case),
# then try to determine it automatically. An extension can only be
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index b0c272ed30..ae1998e241 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -33,7 +33,7 @@ import six
import llnl.util.filesystem as fsys
import llnl.util.tty as tty
-from llnl.util.lang import match_predicate, memoized, nullcontext
+from llnl.util.lang import classproperty, match_predicate, memoized, nullcontext
from llnl.util.link_tree import LinkTree
import spack.compilers
@@ -50,6 +50,7 @@ import spack.mixins
import spack.multimethod
import spack.paths
import spack.repo
+import spack.spec
import spack.store
import spack.url
import spack.util.environment
@@ -207,8 +208,8 @@ class DetectablePackageMeta(object):
# If a package has the executables or libraries attribute then it's
# assumed to be detectable
if hasattr(cls, 'executables') or hasattr(cls, 'libraries'):
- @property
- def platform_executables(self):
+ @classmethod
+ def platform_executables(cls):
def to_windows_exe(exe):
if exe.endswith('$'):
exe = exe.replace('$', '%s$' % spack.util.path.win_exe_ext())
@@ -216,8 +217,8 @@ class DetectablePackageMeta(object):
exe += spack.util.path.win_exe_ext()
return exe
plat_exe = []
- if hasattr(self, 'executables'):
- for exe in self.executables:
+ if hasattr(cls, 'executables'):
+ for exe in cls.executables:
if sys.platform == 'win32':
exe = to_windows_exe(exe)
plat_exe.append(exe)
@@ -397,63 +398,6 @@ class PackageMeta(
return func
return _decorator
- @property
- def package_dir(self):
- """Directory where the package.py file lives."""
- return os.path.abspath(os.path.dirname(self.module.__file__))
-
- @property
- def module(self):
- """Module object (not just the name) that this package is defined in.
-
- We use this to add variables to package modules. This makes
- install() methods easier to write (e.g., can call configure())
- """
- return __import__(self.__module__, fromlist=[self.__name__])
-
- @property
- def namespace(self):
- """Spack namespace for the package, which identifies its repo."""
- return spack.repo.namespace_from_fullname(self.__module__)
-
- @property
- def fullname(self):
- """Name of this package, including the namespace"""
- return '%s.%s' % (self.namespace, self.name)
-
- @property
- def fullnames(self):
- """
- Fullnames for this package and any packages from which it inherits.
- """
- fullnames = []
- for cls in inspect.getmro(self):
- namespace = getattr(cls, 'namespace', None)
- if namespace:
- fullnames.append('%s.%s' % (namespace, self.name))
- if namespace == 'builtin':
- # builtin packages cannot inherit from other repos
- break
- return fullnames
-
- @property
- def name(self):
- """The name of this package.
-
- The name of a package is the name of its Python module, without
- the containing module names.
- """
- if self._name is None:
- self._name = self.module.__name__
- if '.' in self._name:
- self._name = self._name[self._name.rindex('.') + 1:]
- return self._name
-
- @property
- def global_license_dir(self):
- """Returns the directory where license files for all packages are stored."""
- return spack.util.path.canonicalize_path(spack.config.get('config:license_dir'))
-
def run_before(*phases):
"""Registers a method of a package to be run before a given phase"""
@@ -806,7 +750,8 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
self._fetch_time = 0.0
if self.is_extension:
- spack.repo.get(self.extendee_spec)._check_extendable()
+ pkg_cls = spack.repo.path.get_pkg_class(self.extendee_spec.name)
+ pkg_cls(self.extendee_spec)._check_extendable()
super(PackageBase, self).__init__()
@@ -902,60 +847,60 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
return visited
- def enum_constraints(self, visited=None):
- """Return transitive dependency constraints on this package."""
- if visited is None:
- visited = set()
- visited.add(self.name)
-
- names = []
- clauses = []
-
- for name in self.dependencies:
- if name not in visited and not spack.spec.Spec(name).virtual:
- pkg = spack.repo.get(name)
- dvis, dnames, dclauses = pkg.enum_constraints(visited)
- visited |= dvis
- names.extend(dnames)
- clauses.extend(dclauses)
-
- return visited
-
- # package_dir and module are *class* properties (see PackageMeta),
- # but to make them work on instances we need these defs as well.
- @property
- def package_dir(self):
+ @classproperty
+ def package_dir(cls):
"""Directory where the package.py file lives."""
- return type(self).package_dir
+ return os.path.abspath(os.path.dirname(cls.module.__file__))
- @property
- def module(self):
- """Module object that this package is defined in."""
- return type(self).module
+ @classproperty
+ def module(cls):
+ """Module object (not just the name) that this package is defined in.
- @property
- def namespace(self):
+ We use this to add variables to package modules. This makes
+ install() methods easier to write (e.g., can call configure())
+ """
+ return __import__(cls.__module__, fromlist=[cls.__name__])
+
+ @classproperty
+ def namespace(cls):
"""Spack namespace for the package, which identifies its repo."""
- return type(self).namespace
+ return spack.repo.namespace_from_fullname(cls.__module__)
- @property
- def fullname(self):
- """Name of this package, including namespace: namespace.name."""
- return type(self).fullname
+ @classproperty
+ def fullname(cls):
+ """Name of this package, including the namespace"""
+ return '%s.%s' % (cls.namespace, cls.name)
- @property
- def fullnames(self):
- return type(self).fullnames
+ @classproperty
+ def fullnames(cls):
+ """Fullnames for this package and any packages from which it inherits."""
+ fullnames = []
+ for cls in inspect.getmro(cls):
+ namespace = getattr(cls, 'namespace', None)
+ if namespace:
+ fullnames.append('%s.%s' % (namespace, cls.name))
+ if namespace == 'builtin':
+ # builtin packages cannot inherit from other repos
+ break
+ return fullnames
- @property
- def name(self):
- """Name of this package (the module without parent modules)."""
- return type(self).name
+ @classproperty
+ def name(cls):
+ """The name of this package.
- @property
- def global_license_dir(self):
- """Returns the directory where global license files are stored."""
- return type(self).global_license_dir
+ The name of a package is the name of its Python module, without
+ the containing module names.
+ """
+ if cls._name is None:
+ cls._name = cls.module.__name__
+ if '.' in cls._name:
+ cls._name = cls._name[cls._name.rindex('.') + 1:]
+ return cls._name
+
+ @classproperty
+ def global_license_dir(cls):
+ """Returns the directory where license files for all packages are stored."""
+ return spack.util.path.canonicalize_path(spack.config.get('config:license_dir'))
@property
def global_license_file(self):
@@ -973,8 +918,9 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
" does not have a concrete version.")
return self.spec.versions[0]
+ @classmethod
@memoized
- def version_urls(self):
+ def version_urls(cls):
"""OrderedDict of explicitly defined URLs for versions of this package.
Return:
@@ -986,7 +932,7 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
if a package only defines ``url`` at the top level.
"""
version_urls = collections.OrderedDict()
- for v, args in sorted(self.versions.items()):
+ for v, args in sorted(cls.versions.items()):
if 'url' in args:
version_urls[v] = args['url']
return version_urls
@@ -1026,14 +972,12 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
"""
return self._implement_all_urls_for_version(version)[0]
- def all_urls_for_version(self, version, custom_url_for_version=None):
- """Returns all URLs derived from version_urls(), url, urls, and
+ def all_urls_for_version(self, version):
+ """Return all URLs derived from version_urls(), url, urls, and
list_url (if it contains a version) in a package in that order.
- version: class Version
- The version for which a URL is sought.
-
- See Class Version (version.py)
+ Args:
+ version (spack.version.Version): the version for which a URL is sought
"""
uf = None
if type(self).url_for_version != Package.url_for_version:
@@ -1329,7 +1273,8 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
self._fetcher = f
self._fetcher.set_package(self)
- def dependencies_of_type(self, *deptypes):
+ @classmethod
+ def dependencies_of_type(cls, *deptypes):
"""Get dependencies that can possibly have these deptypes.
This analyzes the package and determines which dependencies *can*
@@ -1339,8 +1284,8 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
run dependency in another.
"""
return dict(
- (name, conds) for name, conds in self.dependencies.items()
- if any(dt in self.dependencies[name][cond].type
+ (name, conds) for name, conds in cls.dependencies.items()
+ if any(dt in cls.dependencies[name][cond].type
for cond in conds for dt in deptypes))
@property
@@ -1371,8 +1316,8 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
# TODO: do something sane here with more than one extendee
# If it's not concrete, then return the spec from the
# extends() directive since that is all we know so far.
- spec, kwargs = next(iter(self.extendees.items()))
- return spec
+ spec_str, kwargs = next(iter(self.extendees.items()))
+ return spack.spec.Spec(spec_str)
@property
def extendee_args(self):
@@ -2707,14 +2652,15 @@ class PackageBase(six.with_metaclass(PackageMeta, PackageViewMixin, object)):
self.stage.destroy()
- def format_doc(self, **kwargs):
+ @classmethod
+ def format_doc(cls, **kwargs):
"""Wrap doc string at 72 characters and format nicely"""
indent = kwargs.get('indent', 0)
- if not self.__doc__:
+ if not cls.__doc__:
return ""
- doc = re.sub(r'\s+', ' ', self.__doc__)
+ doc = re.sub(r'\s+', ' ', cls.__doc__)
lines = textwrap.wrap(doc, 72)
results = six.StringIO()
for line in lines:
diff --git a/lib/spack/spack/package_prefs.py b/lib/spack/spack/package_prefs.py
index f49d6940da..7c5e1231fc 100644
--- a/lib/spack/spack/package_prefs.py
+++ b/lib/spack/spack/package_prefs.py
@@ -138,8 +138,8 @@ class PackagePrefs(object):
@classmethod
def preferred_variants(cls, pkg_name):
"""Return a VariantMap of preferred variants/values for a spec."""
- for pkg in (pkg_name, 'all'):
- variants = spack.config.get('packages').get(pkg, {}).get(
+ for pkg_cls in (pkg_name, 'all'):
+ variants = spack.config.get('packages').get(pkg_cls, {}).get(
'variants', '')
if variants:
break
@@ -149,21 +149,26 @@ class PackagePrefs(object):
variants = " ".join(variants)
# Only return variants that are actually supported by the package
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
spec = spack.spec.Spec("%s %s" % (pkg_name, variants))
return dict((name, variant) for name, variant in spec.variants.items()
- if name in pkg.variants)
+ if name in pkg_cls.variants)
def spec_externals(spec):
"""Return a list of external specs (w/external directory path filled in),
- one for each known external installation."""
+ one for each known external installation.
+ """
# break circular import.
from spack.util.module_cmd import path_from_modules # NOQA: ignore=F401
+ def _package(maybe_abstract_spec):
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
+ return pkg_cls(maybe_abstract_spec)
+
allpkgs = spack.config.get('packages')
names = set([spec.name])
- names |= set(vspec.name for vspec in spec.package.virtuals_provided)
+ names |= set(vspec.name for vspec in _package(spec).virtuals_provided)
external_specs = []
for name in names:
@@ -190,17 +195,21 @@ def spec_externals(spec):
def is_spec_buildable(spec):
- """Return true if the spec pkgspec is configured as buildable"""
+ """Return true if the spec is configured as buildable"""
allpkgs = spack.config.get('packages')
all_buildable = allpkgs.get('all', {}).get('buildable', True)
+ def _package(s):
+ pkg_cls = spack.repo.path.get_pkg_class(s.name)
+ return pkg_cls(s)
+
# Get the list of names for which all_buildable is overridden
reverse = [name for name, entry in allpkgs.items()
if entry.get('buildable', all_buildable) != all_buildable]
# Does this spec override all_buildable
spec_reversed = (spec.name in reverse or
- any(spec.package.provides(name) for name in reverse))
+ any(_package(spec).provides(name) for name in reverse))
return not all_buildable if spec_reversed else all_buildable
diff --git a/lib/spack/spack/patch.py b/lib/spack/spack/patch.py
index 237e85ad75..47daf9ecc7 100644
--- a/lib/spack/spack/patch.py
+++ b/lib/spack/spack/patch.py
@@ -284,11 +284,11 @@ def from_dict(dictionary):
owner = dictionary.get('owner')
if 'owner' not in dictionary:
raise ValueError('Invalid patch dictionary: %s' % dictionary)
- pkg = spack.repo.get(owner)
+ pkg_cls = spack.repo.path.get_pkg_class(owner)
if 'url' in dictionary:
return UrlPatch(
- pkg,
+ pkg_cls,
dictionary['url'],
dictionary['level'],
dictionary['working_dir'],
@@ -297,7 +297,7 @@ def from_dict(dictionary):
elif 'relative_path' in dictionary:
patch = FilePatch(
- pkg,
+ pkg_cls,
dictionary['relative_path'],
dictionary['level'],
dictionary['working_dir'])
@@ -404,8 +404,8 @@ class PatchCache(object):
del self.index[sha256]
# update the index with per-package patch indexes
- pkg = spack.repo.get(pkg_fullname)
- partial_index = self._index_patches(pkg)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_fullname)
+ partial_index = self._index_patches(pkg_cls)
for sha256, package_to_patch in partial_index.items():
p2p = self.index.setdefault(sha256, {})
p2p.update(package_to_patch)
@@ -432,10 +432,10 @@ class PatchCache(object):
for cond, dependency in conditions.items():
for pcond, patch_list in dependency.patches.items():
for patch in patch_list:
- dspec = spack.repo.get(dependency.spec.name)
+ dspec_cls = spack.repo.path.get_pkg_class(dependency.spec.name)
patch_dict = patch.to_dict()
patch_dict.pop('sha256') # save some space
- index[patch.sha256] = {dspec.fullname: patch_dict}
+ index[patch.sha256] = {dspec_cls.fullname: patch_dict}
return index
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py
index 82ac03ecdc..8d10de4818 100644
--- a/lib/spack/spack/repo.py
+++ b/lib/spack/spack/repo.py
@@ -862,10 +862,6 @@ class RepoPath(object):
r |= set(repo.packages_with_tags(*tags))
return sorted(r)
- def all_packages(self):
- for name in self.all_package_names():
- yield self.get(name)
-
def all_package_classes(self):
for name in self.all_package_names():
yield self.get_pkg_class(name)
@@ -909,7 +905,9 @@ class RepoPath(object):
@autospec
def extensions_for(self, extendee_spec):
- return [p for p in self.all_packages() if p.extends(extendee_spec)]
+ return [pkg_cls(spack.spec.Spec(pkg_cls.name))
+ for pkg_cls in self.all_package_classes()
+ if pkg_cls(spack.spec.Spec(pkg_cls.name)).extends(extendee_spec)]
def last_mtime(self):
"""Time a package file in this repo was last updated."""
@@ -945,9 +943,10 @@ class RepoPath(object):
# that can operate on packages that don't exist yet.
return self.first_repo()
- @autospec
def get(self, spec):
"""Returns the package associated with the supplied spec."""
+ msg = "RepoPath.get can only be called on concrete specs"
+ assert isinstance(spec, spack.spec.Spec) and spec.concrete, msg
return self.repo_for_pkg(spec).get(spec)
def get_pkg_class(self, pkg_name):
@@ -1107,9 +1106,10 @@ class Repo(object):
tty.die("Error reading %s when opening %s"
% (self.config_file, self.root))
- @autospec
def get(self, spec):
"""Returns the package associated with the supplied spec."""
+ msg = "Repo.get can only be called on concrete specs"
+ assert isinstance(spec, spack.spec.Spec) and spec.concrete, msg
# NOTE: we only check whether the package is None here, not whether it
# actually exists, because we have to load it anyway, and that ends up
# checking for existence. We avoid constructing FastPackageChecker,
@@ -1199,7 +1199,9 @@ class Repo(object):
@autospec
def extensions_for(self, extendee_spec):
- return [p for p in self.all_packages() if p.extends(extendee_spec)]
+ return [pkg_cls(spack.spec.Spec(pkg_cls.name))
+ for pkg_cls in self.all_package_classes()
+ if pkg_cls(spack.spec.Spec(pkg_cls.name)).extends(extendee_spec)]
def dirname_for_package_name(self, pkg_name):
"""Get the directory name for a particular package. This is the
@@ -1241,15 +1243,6 @@ class Repo(object):
return sorted(v)
- def all_packages(self):
- """Iterator over all packages in the repository.
-
- Use this with care, because loading packages is slow.
-
- """
- for name in self.all_package_names():
- yield self.get(name)
-
def all_package_classes(self):
"""Iterator over all package *classes* in the repository.
@@ -1398,11 +1391,6 @@ path = llnl.util.lang.Singleton(_path)
sys.meta_path.append(ReposFinder())
-def get(spec):
- """Convenience wrapper around ``spack.repo.get()``."""
- return path.get(spec)
-
-
def all_package_names(include_virtuals=False):
"""Convenience wrapper around ``spack.repo.all_package_names()``."""
return path.all_package_names(include_virtuals)
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 5a466ab78a..dc1c93eacd 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -1310,13 +1310,16 @@ class SpackSolverSetup(object):
if not spec.concrete:
reserved_names = spack.directives.reserved_names
if not spec.virtual and vname not in reserved_names:
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
try:
- variant_def, _ = spec.package.variants[vname]
+ variant_def, _ = pkg_cls.variants[vname]
except KeyError:
msg = 'variant "{0}" not found in package "{1}"'
raise RuntimeError(msg.format(vname, spec.name))
else:
- variant_def.validate_or_raise(variant, spec.package)
+ variant_def.validate_or_raise(
+ variant, spack.repo.path.get_pkg_class(spec.name)
+ )
clauses.append(f.variant_value(spec.name, vname, value))
@@ -1391,7 +1394,7 @@ class SpackSolverSetup(object):
packages_yaml = spack.config.get("packages")
packages_yaml = _normalize_packages_yaml(packages_yaml)
for pkg_name in possible_pkgs:
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
# All the versions from the corresponding package.py file. Since concepts
# like being a "develop" version or being preferred exist only at a
@@ -1404,7 +1407,7 @@ class SpackSolverSetup(object):
return info.get('preferred', False), not version.isdevelop(), version
for idx, item in enumerate(sorted(
- pkg.versions.items(), key=key_fn, reverse=True
+ pkg_cls.versions.items(), key=key_fn, reverse=True
)):
v, version_info = item
self.possible_versions[pkg_name].add(v)
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 7ebb34894d..94559d001c 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1517,8 +1517,9 @@ class Spec(object):
@property
def package(self):
+ assert self.concrete, "Spec.package can only be called on concrete specs"
if not self._package:
- self._package = spack.repo.get(self)
+ self._package = spack.repo.path.get(self)
return self._package
@property
@@ -2500,8 +2501,9 @@ class Spec(object):
assert isinstance(self.extra_attributes, Mapping), msg
# Validate the spec calling a package specific method
+ pkg_cls = spack.repo.path.get_pkg_class(self.name)
validate_fn = getattr(
- self.package, 'validate_detected_spec', lambda x, y: None
+ pkg_cls, 'validate_detected_spec', lambda x, y: None
)
validate_fn(self, self.extra_attributes)
@@ -2729,7 +2731,8 @@ class Spec(object):
visited_user_specs = set()
for dep in self.traverse():
visited_user_specs.add(dep.name)
- visited_user_specs.update(x.name for x in dep.package.provided)
+ pkg_cls = spack.repo.path.get_pkg_class(dep.name)
+ visited_user_specs.update(x.name for x in pkg_cls(dep).provided)
extra = set(user_spec_deps.keys()).difference(visited_user_specs)
if extra:
@@ -2863,10 +2866,12 @@ class Spec(object):
for mod in compiler.modules:
md.load_module(mod)
- # get the path from the module
- # the package can override the default
+ # Get the path from the module the package can override the default
+ # (this is mostly needed for Cray)
+ pkg_cls = spack.repo.path.get_pkg_class(external_spec.name)
+ package = pkg_cls(external_spec)
external_spec.external_path = getattr(
- external_spec.package, 'external_prefix',
+ package, 'external_prefix',
md.path_from_modules(external_spec.external_modules)
)
@@ -3377,7 +3382,7 @@ class Spec(object):
for spec in self.traverse():
# raise an UnknownPackageError if the spec's package isn't real.
if (not spec.virtual) and spec.name:
- spack.repo.get(spec.fullname)
+ spack.repo.path.get_pkg_class(spec.fullname)
# validate compiler in addition to the package name.
if spec.compiler:
@@ -3444,8 +3449,8 @@ class Spec(object):
variant = pkg_variant.make_variant(value)
self.variants[variant_name] = variant
- pkg_variant.validate_or_raise(
- self.variants[variant_name], self.package)
+ pkg_cls = spack.repo.path.get_pkg_class(self.name)
+ pkg_variant.validate_or_raise(self.variants[variant_name], pkg_cls)
def constrain(self, other, deps=True):
"""Merge the constraints of other with self.
@@ -3633,7 +3638,9 @@ class Spec(object):
# A concrete provider can satisfy a virtual dependency.
if not self.virtual and other.virtual:
try:
- pkg = spack.repo.get(self.fullname)
+ # Here we might get an abstract spec
+ pkg_cls = spack.repo.path.get_pkg_class(self.fullname)
+ pkg = pkg_cls(self)
except spack.repo.UnknownEntityError:
# If we can't get package info on this spec, don't treat
# it as a provider of this vdep.
@@ -3771,7 +3778,8 @@ class Spec(object):
if self._patches_assigned():
for sha256 in self.variants["patches"]._patches_in_order_of_appearance:
index = spack.repo.path.patch_index
- patch = index.patch_for_package(sha256, self.package)
+ pkg_cls = spack.repo.path.get_pkg_class(self.name)
+ patch = index.patch_for_package(sha256, pkg_cls)
self._patches.append(patch)
return self._patches
diff --git a/lib/spack/spack/tag.py b/lib/spack/spack/tag.py
index 77ba698e66..86988738b0 100644
--- a/lib/spack/spack/tag.py
+++ b/lib/spack/spack/tag.py
@@ -118,7 +118,7 @@ class TagIndex(Mapping):
pkg_name (str): name of the package to be removed from the index
"""
- package = spack.repo.path.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
# Remove the package from the list of packages, if present
for pkg_list in self._tag_dict.values():
@@ -126,9 +126,9 @@ class TagIndex(Mapping):
pkg_list.remove(pkg_name)
# Add it again under the appropriate tags
- for tag in getattr(package, 'tags', []):
+ for tag in getattr(pkg_cls, 'tags', []):
tag = tag.lower()
- self._tag_dict[tag].append(package.name)
+ self._tag_dict[tag].append(pkg_cls.name)
class TagIndexError(spack.error.SpackError):
diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py
index 304fa4c7bd..c59e28a180 100644
--- a/lib/spack/spack/test/build_systems.py
+++ b/lib/spack/spack/test/build_systems.py
@@ -7,6 +7,7 @@ import glob
import os
import sys
+import py.path
import pytest
import llnl.util.filesystem as fs
@@ -24,131 +25,77 @@ pytestmark = pytest.mark.skipif(sys.platform == "win32",
reason="does not run on windows")
-@pytest.mark.parametrize(
- 'directory',
- glob.iglob(os.path.join(DATA_PATH, 'make', 'affirmative', '*'))
-)
-def test_affirmative_make_check(directory, config, mock_packages, working_env):
- """Tests that Spack correctly detects targets in a Makefile."""
-
- # Get a fake package
- s = Spec('mpich')
- s.concretize()
- pkg = spack.repo.get(s)
- setup_package(pkg, False)
-
- with fs.working_dir(directory):
- assert pkg._has_make_target('check')
-
- pkg._if_make_target_execute('check')
-
-
-@pytest.mark.parametrize(
- 'directory',
- glob.iglob(os.path.join(DATA_PATH, 'make', 'negative', '*'))
-)
-@pytest.mark.regression('9067')
-def test_negative_make_check(directory, config, mock_packages, working_env):
- """Tests that Spack correctly ignores false positives in a Makefile."""
-
- # Get a fake package
- s = Spec('mpich')
- s.concretize()
- pkg = spack.repo.get(s)
- setup_package(pkg, False)
-
- with fs.working_dir(directory):
- assert not pkg._has_make_target('check')
-
- pkg._if_make_target_execute('check')
-
-
-@pytest.mark.skipif(not which('ninja'), reason='ninja is not installed')
-@pytest.mark.parametrize(
- 'directory',
- glob.iglob(os.path.join(DATA_PATH, 'ninja', 'affirmative', '*'))
-)
-def test_affirmative_ninja_check(
- directory, config, mock_packages, working_env):
- """Tests that Spack correctly detects targets in a Ninja build script."""
-
- # Get a fake package
- s = Spec('mpich')
- s.concretize()
- pkg = spack.repo.get(s)
- setup_package(pkg, False)
-
- with fs.working_dir(directory):
- assert pkg._has_ninja_target('check')
-
- pkg._if_ninja_target_execute('check')
-
- # Clean up Ninja files
- for filename in glob.iglob('.ninja_*'):
- os.remove(filename)
-
-
-@pytest.mark.skipif(not which('ninja'), reason='ninja is not installed')
-@pytest.mark.parametrize(
- 'directory',
- glob.iglob(os.path.join(DATA_PATH, 'ninja', 'negative', '*'))
-)
-def test_negative_ninja_check(directory, config, mock_packages, working_env):
- """Tests that Spack correctly ignores false positives in a Ninja
- build script."""
-
- # Get a fake package
- s = Spec('mpich')
- s.concretize()
- pkg = spack.repo.get(s)
- setup_package(pkg, False)
-
- with fs.working_dir(directory):
- assert not pkg._has_ninja_target('check')
-
- pkg._if_ninja_target_execute('check')
-
-
-def test_cmake_std_args(config, mock_packages):
- # Call the function on a CMakePackage instance
- s = Spec('cmake-client')
- s.concretize()
- pkg = spack.repo.get(s)
- assert pkg.std_cmake_args == get_std_cmake_args(pkg)
-
- # Call it on another kind of package
- s = Spec('mpich')
- s.concretize()
- pkg = spack.repo.get(s)
- assert get_std_cmake_args(pkg)
-
-
-def test_cmake_bad_generator(config, mock_packages):
- s = Spec('cmake-client')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.generator = 'Yellow Sticky Notes'
- with pytest.raises(spack.package_base.InstallError):
- get_std_cmake_args(pkg)
-
-
-def test_cmake_secondary_generator(config, mock_packages):
- s = Spec('cmake-client')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.generator = 'CodeBlocks - Unix Makefiles'
- assert get_std_cmake_args(pkg)
+@pytest.fixture()
+def concretize_and_setup():
+ def _func(spec_str):
+ s = Spec('mpich').concretized()
+ setup_package(s.package, False)
+ return s
+ return _func
+
+
+@pytest.fixture()
+def test_dir(tmpdir):
+ def _func(dir_str):
+ py.path.local(dir_str).copy(tmpdir)
+ return str(tmpdir)
+ return _func
+
+
+@pytest.mark.usefixtures('config', 'mock_packages', 'working_env')
+class TestTargets(object):
+ @pytest.mark.parametrize(
+ 'input_dir', glob.iglob(os.path.join(DATA_PATH, 'make', 'affirmative', '*'))
+ )
+ def test_affirmative_make_check(self, input_dir, test_dir, concretize_and_setup):
+ """Tests that Spack correctly detects targets in a Makefile."""
+ s = concretize_and_setup('mpich')
+ with fs.working_dir(test_dir(input_dir)):
+ assert s.package._has_make_target('check')
+ s.package._if_make_target_execute('check')
+
+ @pytest.mark.parametrize(
+ 'input_dir', glob.iglob(os.path.join(DATA_PATH, 'make', 'negative', '*'))
+ )
+ @pytest.mark.regression('9067')
+ def test_negative_make_check(self, input_dir, test_dir, concretize_and_setup):
+ """Tests that Spack correctly ignores false positives in a Makefile."""
+ s = concretize_and_setup('mpich')
+ with fs.working_dir(test_dir(input_dir)):
+ assert not s.package._has_make_target('check')
+ s.package._if_make_target_execute('check')
+
+ @pytest.mark.skipif(not which('ninja'), reason='ninja is not installed')
+ @pytest.mark.parametrize(
+ 'input_dir', glob.iglob(os.path.join(DATA_PATH, 'ninja', 'affirmative', '*'))
+ )
+ def test_affirmative_ninja_check(self, input_dir, test_dir, concretize_and_setup):
+ """Tests that Spack correctly detects targets in a Ninja build script."""
+ s = concretize_and_setup('mpich')
+ with fs.working_dir(test_dir(input_dir)):
+ assert s.package._has_ninja_target('check')
+ s.package._if_ninja_target_execute('check')
+
+ @pytest.mark.skipif(not which('ninja'), reason='ninja is not installed')
+ @pytest.mark.parametrize(
+ 'input_dir', glob.iglob(os.path.join(DATA_PATH, 'ninja', 'negative', '*'))
+ )
+ def test_negative_ninja_check(self, input_dir, test_dir, concretize_and_setup):
+ """Tests that Spack correctly ignores false positives in a Ninja
+ build script.
+ """
+ s = concretize_and_setup('mpich')
+ with fs.working_dir(test_dir(input_dir)):
+ assert not s.package._has_ninja_target('check')
+ s.package._if_ninja_target_execute('check')
@pytest.mark.usefixtures('config', 'mock_packages')
class TestAutotoolsPackage(object):
def test_with_or_without(self):
- s = Spec('a')
- s.concretize()
- pkg = spack.repo.get(s)
-
- options = pkg.with_or_without('foo')
+ s = Spec('a').concretized()
+ options = s.package.with_or_without('foo')
# Ensure that values that are not representing a feature
# are not used by with_or_without
@@ -160,30 +107,27 @@ class TestAutotoolsPackage(object):
def activate(value):
return 'something'
- options = pkg.with_or_without('foo', activation_value=activate)
+ options = s.package.with_or_without('foo', activation_value=activate)
assert '--without-none' not in options
assert '--with-bar=something' in options
assert '--without-baz' in options
assert '--no-fee' in options
- options = pkg.enable_or_disable('foo')
+ options = s.package.enable_or_disable('foo')
assert '--disable-none' not in options
assert '--enable-bar' in options
assert '--disable-baz' in options
assert '--disable-fee' in options
- options = pkg.with_or_without('bvv')
+ options = s.package.with_or_without('bvv')
assert '--with-bvv' in options
- options = pkg.with_or_without('lorem-ipsum', variant='lorem_ipsum')
+ options = s.package.with_or_without('lorem-ipsum', variant='lorem_ipsum')
assert '--without-lorem-ipsum' in options
def test_none_is_allowed(self):
- s = Spec('a foo=none')
- s.concretize()
- pkg = spack.repo.get(s)
-
- options = pkg.with_or_without('foo')
+ s = Spec('a foo=none').concretized()
+ options = s.package.with_or_without('foo')
# Ensure that values that are not representing a feature
# are not used by with_or_without
@@ -196,8 +140,7 @@ class TestAutotoolsPackage(object):
self, mutable_database
):
# Install a package that creates a mock libtool archive
- s = Spec('libtool-deletion')
- s.concretize()
+ s = Spec('libtool-deletion').concretized()
s.package.do_install(explicit=True)
# Assert the libtool archive is not there and we have
@@ -214,8 +157,7 @@ class TestAutotoolsPackage(object):
):
# Install a package that creates a mock libtool archive,
# patch its package to preserve the installation
- s = Spec('libtool-deletion')
- s.concretize()
+ s = Spec('libtool-deletion').concretized()
monkeypatch.setattr(s.package, 'install_libtool_archives', True)
s.package.do_install(explicit=True)
@@ -308,135 +250,93 @@ spack:
@pytest.mark.usefixtures('config', 'mock_packages')
class TestCMakePackage(object):
+ def test_cmake_std_args(self):
+ # Call the function on a CMakePackage instance
+ s = Spec('cmake-client').concretized()
+ assert s.package.std_cmake_args == get_std_cmake_args(s.package)
+
+ # Call it on another kind of package
+ s = Spec('mpich').concretized()
+ assert get_std_cmake_args(s.package)
+
+ def test_cmake_bad_generator(self):
+ s = Spec('cmake-client').concretized()
+ s.package.generator = 'Yellow Sticky Notes'
+ with pytest.raises(spack.package_base.InstallError):
+ get_std_cmake_args(s.package)
+
+ def test_cmake_secondary_generator(config, mock_packages):
+ s = Spec('cmake-client').concretized()
+ s.package.generator = 'CodeBlocks - Unix Makefiles'
+ assert get_std_cmake_args(s.package)
def test_define(self):
- s = Spec('cmake-client')
- s.concretize()
- pkg = spack.repo.get(s)
+ s = Spec('cmake-client').concretized()
+ define = s.package.define
for cls in (list, tuple):
- arg = pkg.define('MULTI', cls(['right', 'up']))
- assert arg == '-DMULTI:STRING=right;up'
+ assert define('MULTI', cls(['right', 'up'])) == '-DMULTI:STRING=right;up'
- arg = pkg.define('MULTI', fs.FileList(['/foo', '/bar']))
- assert arg == '-DMULTI:STRING=/foo;/bar'
+ file_list = fs.FileList(['/foo', '/bar'])
+ assert define('MULTI', file_list) == '-DMULTI:STRING=/foo;/bar'
- arg = pkg.define('ENABLE_TRUTH', False)
- assert arg == '-DENABLE_TRUTH:BOOL=OFF'
- arg = pkg.define('ENABLE_TRUTH', True)
- assert arg == '-DENABLE_TRUTH:BOOL=ON'
+ assert define('ENABLE_TRUTH', False) == '-DENABLE_TRUTH:BOOL=OFF'
+ assert define('ENABLE_TRUTH', True) == '-DENABLE_TRUTH:BOOL=ON'
- arg = pkg.define('SINGLE', 'red')
- assert arg == '-DSINGLE:STRING=red'
+ assert define('SINGLE', 'red') == '-DSINGLE:STRING=red'
def test_define_from_variant(self):
- s = Spec('cmake-client multi=up,right ~truthy single=red')
- s.concretize()
- pkg = spack.repo.get(s)
+ s = Spec('cmake-client multi=up,right ~truthy single=red').concretized()
- arg = pkg.define_from_variant('MULTI')
+ arg = s.package.define_from_variant('MULTI')
assert arg == '-DMULTI:STRING=right;up'
- arg = pkg.define_from_variant('ENABLE_TRUTH', 'truthy')
+ arg = s.package.define_from_variant('ENABLE_TRUTH', 'truthy')
assert arg == '-DENABLE_TRUTH:BOOL=OFF'
- arg = pkg.define_from_variant('SINGLE')
+ arg = s.package.define_from_variant('SINGLE')
assert arg == '-DSINGLE:STRING=red'
with pytest.raises(KeyError, match="not a variant"):
- pkg.define_from_variant('NONEXISTENT')
+ s.package.define_from_variant('NONEXISTENT')
@pytest.mark.usefixtures('config', 'mock_packages')
-class TestGNUMirrorPackage(object):
-
- def test_define(self):
- s = Spec('mirror-gnu')
- s.concretize()
- pkg = spack.repo.get(s)
-
- s = Spec('mirror-gnu-broken')
- s.concretize()
- pkg_broken = spack.repo.get(s)
-
- cls_name = type(pkg_broken).__name__
- with pytest.raises(AttributeError,
- match=r'{0} must define a `gnu_mirror_path` '
- r'attribute \[none defined\]'
- .format(cls_name)):
- pkg_broken.urls
-
- assert pkg.urls[0] == 'https://ftpmirror.gnu.org/' \
- 'make/make-4.2.1.tar.gz'
-
-
-@pytest.mark.usefixtures('config', 'mock_packages')
-class TestSourceforgePackage(object):
-
- def test_define(self):
- s = Spec('mirror-sourceforge')
- s.concretize()
- pkg = spack.repo.get(s)
-
- s = Spec('mirror-sourceforge-broken')
- s.concretize()
- pkg_broken = spack.repo.get(s)
-
- cls_name = type(pkg_broken).__name__
- with pytest.raises(AttributeError,
- match=r'{0} must define a `sourceforge_mirror_path`'
- r' attribute \[none defined\]'
- .format(cls_name)):
- pkg_broken.urls
-
- assert pkg.urls[0] == 'https://prdownloads.sourceforge.net/' \
- 'tcl/tcl8.6.5-src.tar.gz'
-
-
-@pytest.mark.usefixtures('config', 'mock_packages')
-class TestSourcewarePackage(object):
-
- def test_define(self):
- s = Spec('mirror-sourceware')
- s.concretize()
- pkg = spack.repo.get(s)
-
- s = Spec('mirror-sourceware-broken')
- s.concretize()
- pkg_broken = spack.repo.get(s)
-
- cls_name = type(pkg_broken).__name__
- with pytest.raises(AttributeError,
- match=r'{0} must define a `sourceware_mirror_path` '
- r'attribute \[none defined\]'
- .format(cls_name)):
- pkg_broken.urls
-
- assert pkg.urls[0] == 'https://sourceware.org/pub/' \
- 'bzip2/bzip2-1.0.8.tar.gz'
-
-
-@pytest.mark.usefixtures('config', 'mock_packages')
-class TestXorgPackage(object):
-
- def test_define(self):
- s = Spec('mirror-xorg')
- s.concretize()
- pkg = spack.repo.get(s)
-
- s = Spec('mirror-xorg-broken')
- s.concretize()
- pkg_broken = spack.repo.get(s)
-
- cls_name = type(pkg_broken).__name__
- with pytest.raises(AttributeError,
- match=r'{0} must define a `xorg_mirror_path` '
- r'attribute \[none defined\]'
- .format(cls_name)):
- pkg_broken.urls
-
- assert pkg.urls[0] == 'https://www.x.org/archive/individual/' \
- 'util/util-macros-1.19.1.tar.bz2'
+class TestDownloadMixins(object):
+ """Test GnuMirrorPackage, SourceforgePackage, SourcewarePackage and XorgPackage."""
+ @pytest.mark.parametrize('spec_str,expected_url', [
+ # GnuMirrorPackage
+ ('mirror-gnu', 'https://ftpmirror.gnu.org/make/make-4.2.1.tar.gz'),
+ # SourceforgePackage
+ ('mirror-sourceforge',
+ 'https://prdownloads.sourceforge.net/tcl/tcl8.6.5-src.tar.gz'),
+ # SourcewarePackage
+ ('mirror-sourceware', 'https://sourceware.org/pub/bzip2/bzip2-1.0.8.tar.gz'),
+ # XorgPackage
+ ('mirror-xorg',
+ 'https://www.x.org/archive/individual/util/util-macros-1.19.1.tar.bz2')
+ ])
+ def test_attributes_defined(self, spec_str, expected_url):
+ s = Spec(spec_str).concretized()
+ assert s.package.urls[0] == expected_url
+
+ @pytest.mark.parametrize('spec_str,error_fmt', [
+ # GnuMirrorPackage
+ ('mirror-gnu-broken', r'{0} must define a `gnu_mirror_path` attribute'),
+ # SourceforgePackage
+ ('mirror-sourceforge-broken',
+ r'{0} must define a `sourceforge_mirror_path` attribute'),
+ # SourcewarePackage
+ ('mirror-sourceware-broken',
+ r'{0} must define a `sourceware_mirror_path` attribute'),
+ # XorgPackage
+ ('mirror-xorg-broken', r'{0} must define a `xorg_mirror_path` attribute'),
+ ])
+ def test_attributes_missing(self, spec_str, error_fmt):
+ s = Spec(spec_str).concretized()
+ error_msg = error_fmt.format(type(s.package).__name__)
+ with pytest.raises(AttributeError, match=error_msg):
+ s.package.urls
def test_cmake_define_from_variant_conditional(config, mock_packages):
diff --git a/lib/spack/spack/test/buildrequest.py b/lib/spack/spack/test/buildrequest.py
index a4ae76086a..f8b62c44d3 100644
--- a/lib/spack/spack/test/buildrequest.py
+++ b/lib/spack/spack/test/buildrequest.py
@@ -23,9 +23,10 @@ def test_build_request_errors(install_mockery):
with pytest.raises(ValueError, match='must be a package'):
inst.BuildRequest('abc', {})
- pkg = spack.repo.get('trivial-install-test-package')
+ spec = spack.spec.Spec('trivial-install-test-package')
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
with pytest.raises(ValueError, match='must have a concrete spec'):
- inst.BuildRequest(pkg, {})
+ inst.BuildRequest(pkg_cls(spec), {})
def test_build_request_basics(install_mockery):
diff --git a/lib/spack/spack/test/buildtask.py b/lib/spack/spack/test/buildtask.py
index c030397be6..b3fe96c42b 100644
--- a/lib/spack/spack/test/buildtask.py
+++ b/lib/spack/spack/test/buildtask.py
@@ -14,11 +14,11 @@ def test_build_task_errors(install_mockery):
with pytest.raises(ValueError, match='must be a package'):
inst.BuildTask('abc', None, False, 0, 0, 0, [])
- pkg = spack.repo.get('trivial-install-test-package')
+ spec = spack.spec.Spec('trivial-install-test-package')
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
with pytest.raises(ValueError, match='must have a concrete spec'):
- inst.BuildTask(pkg, None, False, 0, 0, 0, [])
+ inst.BuildTask(pkg_cls(spec), None, False, 0, 0, 0, [])
- spec = spack.spec.Spec('trivial-install-test-package')
spec.concretize()
assert spec.concrete
with pytest.raises(ValueError, match='must have a build request'):
diff --git a/lib/spack/spack/test/cmd/checksum.py b/lib/spack/spack/test/cmd/checksum.py
index 3c47f69d48..d22636a3d2 100644
--- a/lib/spack/spack/test/cmd/checksum.py
+++ b/lib/spack/spack/test/cmd/checksum.py
@@ -57,9 +57,8 @@ def test_checksum_interactive(
def test_checksum_versions(mock_packages, mock_fetch, mock_stage):
- pkg = spack.repo.get('preferred-test')
-
- versions = [str(v) for v in pkg.versions if not v.isdevelop()]
+ pkg_cls = spack.repo.path.get_pkg_class('preferred-test')
+ versions = [str(v) for v in pkg_cls.versions if not v.isdevelop()]
output = spack_checksum('preferred-test', versions[0])
assert 'Found 1 version' in output
assert 'version(' in output
diff --git a/lib/spack/spack/test/cmd/dev_build.py b/lib/spack/spack/test/cmd/dev_build.py
index 7aa3b58d65..bd1abdf2d6 100644
--- a/lib/spack/spack/test/cmd/dev_build.py
+++ b/lib/spack/spack/test/cmd/dev_build.py
@@ -262,17 +262,19 @@ def test_dev_build_multiple(tmpdir, mock_packages, install_mockery,
# root and dependency if they wanted a dev build for both.
leaf_dir = tmpdir.mkdir('leaf')
leaf_spec = spack.spec.Spec('dev-build-test-install@0.0.0')
+ leaf_pkg_cls = spack.repo.path.get_pkg_class(leaf_spec.name)
with leaf_dir.as_cwd():
- with open(leaf_spec.package.filename, 'w') as f:
- f.write(leaf_spec.package.original_string)
+ with open(leaf_pkg_cls.filename, 'w') as f:
+ f.write(leaf_pkg_cls.original_string)
# setup dev-build-test-dependent package for dev build
# don't concretize outside environment -- dev info will be wrong
root_dir = tmpdir.mkdir('root')
root_spec = spack.spec.Spec('dev-build-test-dependent@0.0.0')
+ root_pkg_cls = spack.repo.path.get_pkg_class(root_spec.name)
with root_dir.as_cwd():
- with open(root_spec.package.filename, 'w') as f:
- f.write(root_spec.package.original_string)
+ with open(root_pkg_cls.filename, 'w') as f:
+ f.write(root_pkg_cls.original_string)
# setup environment
envdir = tmpdir.mkdir('env')
@@ -319,8 +321,9 @@ def test_dev_build_env_dependency(tmpdir, mock_packages, install_mockery,
dep_spec = spack.spec.Spec('dev-build-test-install')
with build_dir.as_cwd():
- with open(dep_spec.package.filename, 'w') as f:
- f.write(dep_spec.package.original_string)
+ dep_pkg_cls = spack.repo.path.get_pkg_class(dep_spec.name)
+ with open(dep_pkg_cls.filename, 'w') as f:
+ f.write(dep_pkg_cls.original_string)
# setup environment
envdir = tmpdir.mkdir('env')
diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py
index 5d101e53f8..325815451b 100644
--- a/lib/spack/spack/test/cmd/develop.py
+++ b/lib/spack/spack/test/cmd/develop.py
@@ -22,7 +22,8 @@ pytestmark = pytest.mark.skipif(sys.platform == "win32",
@pytest.mark.usefixtures(
- 'mutable_mock_env_path', 'mock_packages', 'mock_fetch')
+ 'mutable_mock_env_path', 'mock_packages', 'mock_fetch', 'config'
+)
class TestDevelop(object):
def check_develop(self, env, spec, path=None):
path = path or spec.name
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index ba67e98a3c..7fcdecdbdb 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -452,9 +452,9 @@ def test_env_repo():
with ev.read('test'):
concretize()
- package = e.repo.get('mpileaks')
- assert package.name == 'mpileaks'
- assert package.namespace == 'builtin.mock'
+ pkg_cls = e.repo.get_pkg_class('mpileaks')
+ assert pkg_cls.name == 'mpileaks'
+ assert pkg_cls.namespace == 'builtin.mock'
def test_user_removed_spec():
diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py
index 0074bee2a9..0ee857ae53 100644
--- a/lib/spack/spack/test/cmd/external.py
+++ b/lib/spack/spack/test/cmd/external.py
@@ -45,7 +45,7 @@ def define_plat_exe(exe):
def test_find_external_single_package(mock_executable, executables_found,
_platform_executables):
- pkgs_to_check = [spack.repo.get('cmake')]
+ pkgs_to_check = [spack.repo.path.get_pkg_class('cmake')]
executables_found({
mock_executable("cmake", output='echo cmake version 1.foo'):
define_plat_exe('cmake')
@@ -61,7 +61,7 @@ def test_find_external_single_package(mock_executable, executables_found,
def test_find_external_two_instances_same_package(mock_executable, executables_found,
_platform_executables):
- pkgs_to_check = [spack.repo.get('cmake')]
+ pkgs_to_check = [spack.repo.path.get_pkg_class('cmake')]
# Each of these cmake instances is created in a different prefix
# In Windows, quoted strings are echo'd with quotes includes
diff --git a/lib/spack/spack/test/cmd/location.py b/lib/spack/spack/test/cmd/location.py
index fe73607a18..ca7b302214 100644
--- a/lib/spack/spack/test/cmd/location.py
+++ b/lib/spack/spack/test/cmd/location.py
@@ -27,16 +27,13 @@ env = SpackCommand('env')
@pytest.fixture
def mock_spec():
- spec = spack.spec.Spec('externaltest').concretized()
- pkg = spack.repo.get(spec)
-
# Make it look like the source was actually expanded.
- source_path = pkg.stage.source_path
+ s = spack.spec.Spec('externaltest').concretized()
+ source_path = s.package.stage.source_path
mkdirp(source_path)
- yield spec, pkg
-
+ yield s, s.package
# Remove the spec from the mock stage area.
- shutil.rmtree(pkg.stage.path)
+ shutil.rmtree(s.package.stage.path)
def test_location_build_dir(mock_spec):
diff --git a/lib/spack/spack/test/cmd/mirror.py b/lib/spack/spack/test/cmd/mirror.py
index e2d936c0a3..0090e78e86 100644
--- a/lib/spack/spack/test/cmd/mirror.py
+++ b/lib/spack/spack/test/cmd/mirror.py
@@ -85,13 +85,13 @@ def test_mirror_from_env(tmpdir, mock_packages, mock_fetch, config,
@pytest.fixture
def source_for_pkg_with_hash(mock_packages, tmpdir):
- pkg = spack.repo.get('trivial-pkg-with-valid-hash')
- local_url_basename = os.path.basename(pkg.url)
+ s = spack.spec.Spec('trivial-pkg-with-valid-hash').concretized()
+ local_url_basename = os.path.basename(s.package.url)
local_path = os.path.join(str(tmpdir), local_url_basename)
with open(local_path, 'w') as f:
- f.write(pkg.hashed_content)
+ f.write(s.package.hashed_content)
local_url = "file://" + local_path
- pkg.versions[spack.version.Version('1.0')]['url'] = local_url
+ s.package.versions[spack.version.Version('1.0')]['url'] = local_url
def test_mirror_skip_unstable(tmpdir_factory, mock_packages, config,
diff --git a/lib/spack/spack/test/cmd/tags.py b/lib/spack/spack/test/cmd/tags.py
index 16aca5182a..91c4621fb8 100644
--- a/lib/spack/spack/test/cmd/tags.py
+++ b/lib/spack/spack/test/cmd/tags.py
@@ -47,9 +47,8 @@ def test_tags_no_tags(monkeypatch):
def test_tags_installed(install_mockery, mock_fetch):
- spec = spack.spec.Spec('mpich').concretized()
- pkg = spack.repo.get(spec)
- pkg.do_install()
+ s = spack.spec.Spec('mpich').concretized()
+ s.package.do_install()
out = tags('-i')
for tag in ['tag1', 'tag2']:
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 25728a0c13..845504ff0c 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -22,7 +22,6 @@ import spack.repo
import spack.variant as vt
from spack.concretize import find_spec
from spack.spec import Spec
-from spack.util.mock_package import MockPackageMultiRepo
from spack.version import ver
is_windows = sys.platform == 'win32'
@@ -44,7 +43,7 @@ def check_spec(abstract, concrete):
cflag = concrete.compiler_flags[flag]
assert set(aflag) <= set(cflag)
- for name in abstract.package.variants:
+ for name in spack.repo.path.get_pkg_class(abstract.name).variants:
assert name in concrete.variants
for flag in concrete.compiler_flags.valid_compiler_flags():
@@ -356,20 +355,11 @@ class TestConcretize(object):
information from the root even when partial architecture information
is provided by an intermediate dependency.
"""
- default_dep = ('link', 'build')
-
- mock_repo = MockPackageMultiRepo()
- bazpkg = mock_repo.add_package('bazpkg', [], [])
- barpkg = mock_repo.add_package('barpkg', [bazpkg], [default_dep])
- mock_repo.add_package('foopkg', [barpkg], [default_dep])
-
- with spack.repo.use_repositories(mock_repo):
- spec = Spec('foopkg %gcc@4.5.0 os=CNL target=nocona' +
- ' ^barpkg os=CNL ^bazpkg os=CNL')
- spec.concretize()
-
- for s in spec.traverse(root=False):
- assert s.architecture.target == spec.architecture.target
+ spec_str = ('mpileaks %gcc@4.5.0 os=CNL target=nocona'
+ ' ^dyninst os=CNL ^callpath os=CNL')
+ spec = Spec(spec_str).concretized()
+ for s in spec.traverse(root=False):
+ assert s.architecture.target == spec.architecture.target
def test_compiler_flags_from_user_are_grouped(self):
spec = Spec('a%gcc cflags="-O -foo-flag foo-val" platform=test')
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index eae3afa265..e014941e94 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -1160,15 +1160,16 @@ def test_bad_path_double_override(config):
def test_license_dir_config(mutable_config, mock_packages):
"""Ensure license directory is customizable"""
- assert spack.config.get("config:license_dir") == spack.paths.default_license_dir
- assert spack.package.Package.global_license_dir == spack.paths.default_license_dir
- assert spack.repo.get("a").global_license_dir == spack.paths.default_license_dir
+ expected_dir = spack.paths.default_license_dir
+ assert spack.config.get("config:license_dir") == expected_dir
+ assert spack.package.Package.global_license_dir == expected_dir
+ assert spack.repo.path.get_pkg_class("a").global_license_dir == expected_dir
rel_path = os.path.join(os.path.sep, "foo", "bar", "baz")
spack.config.set("config:license_dir", rel_path)
assert spack.config.get("config:license_dir") == rel_path
assert spack.package.Package.global_license_dir == rel_path
- assert spack.repo.get("a").global_license_dir == rel_path
+ assert spack.repo.path.get_pkg_class("a").global_license_dir == rel_path
@pytest.mark.regression('22547')
diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py
index 089a073e09..f789fcd9c5 100644
--- a/lib/spack/spack/test/conftest.py
+++ b/lib/spack/spack/test/conftest.py
@@ -751,8 +751,7 @@ def _populate(mock_db):
"""
def _install(spec):
s = spack.spec.Spec(spec).concretized()
- pkg = spack.repo.get(s)
- pkg.do_install(fake=True, explicit=True)
+ s.package.do_install(fake=True, explicit=True)
_install('mpileaks ^mpich')
_install('mpileaks ^mpich2')
diff --git a/lib/spack/spack/test/cvs_fetch.py b/lib/spack/spack/test/cvs_fetch.py
index 7c82f37f2d..ac2f57c341 100644
--- a/lib/spack/spack/test/cvs_fetch.py
+++ b/lib/spack/spack/test/cvs_fetch.py
@@ -9,8 +9,6 @@ import pytest
from llnl.util.filesystem import mkdirp, touch, working_dir
-import spack.config
-import spack.repo
from spack.fetch_strategy import CvsFetchStrategy
from spack.spec import Spec
from spack.stage import Stage
@@ -47,16 +45,14 @@ def test_fetch(
get_date = mock_cvs_repository.get_date
# Construct the package under test
- spec = Spec('cvs-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- pkg.versions[ver('cvs')] = test.args
+ spec = Spec('cvs-test').concretized()
+ spec.package.versions[ver('cvs')] = test.args
# Enter the stage directory and check some properties
- with pkg.stage:
- pkg.do_stage()
+ with spec.package.stage:
+ spec.package.do_stage()
- with working_dir(pkg.stage.source_path):
+ with working_dir(spec.package.stage.source_path):
# Check branch
if test.branch is not None:
assert get_branch() == test.branch
@@ -65,8 +61,8 @@ def test_fetch(
if test.date is not None:
assert get_date() <= test.date
- file_path = os.path.join(pkg.stage.source_path, test.file)
- assert os.path.isdir(pkg.stage.source_path)
+ file_path = os.path.join(spec.package.stage.source_path, test.file)
+ assert os.path.isdir(spec.package.stage.source_path)
assert os.path.isfile(file_path)
os.unlink(file_path)
@@ -75,10 +71,10 @@ def test_fetch(
untracked_file = 'foobarbaz'
touch(untracked_file)
assert os.path.isfile(untracked_file)
- pkg.do_restage()
+ spec.package.do_restage()
assert not os.path.isfile(untracked_file)
- assert os.path.isdir(pkg.stage.source_path)
+ assert os.path.isdir(spec.package.stage.source_path)
assert os.path.isfile(file_path)
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index e61a46cbc5..4c5c0539df 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -401,10 +401,8 @@ def _check_remove_and_add_package(database, spec):
def _mock_install(spec):
- s = spack.spec.Spec(spec)
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.do_install(fake=True)
+ s = spack.spec.Spec(spec).concretized()
+ s.package.do_install(fake=True)
def _mock_remove(spec):
diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py
index 3bacd97ffa..6918e015c4 100644
--- a/lib/spack/spack/test/directory_layout.py
+++ b/lib/spack/spack/test/directory_layout.py
@@ -87,18 +87,17 @@ def test_read_and_write_spec(temporary_store, config, mock_packages):
layout.
"""
layout = temporary_store.layout
- packages = list(spack.repo.path.all_packages())[:max_packages]
+ pkg_names = list(spack.repo.path.all_package_names())[:max_packages]
- for pkg in packages:
- if pkg.name.startswith('external'):
+ for name in pkg_names:
+ if name.startswith('external'):
# External package tests cannot be installed
continue
- spec = pkg.spec
# If a spec fails to concretize, just skip it. If it is a
# real error, it will be caught by concretization tests.
try:
- spec.concretize()
+ spec = spack.spec.Spec(name).concretized()
except Exception:
continue
@@ -171,7 +170,7 @@ def test_handle_unknown_package(temporary_store, config, mock_packages):
# Create all the packages that are not in mock.
installed_specs = {}
for pkg_name in packages:
- spec = spack.repo.get(pkg_name).spec
+ spec = spack.spec.Spec(pkg_name)
# If a spec fails to concretize, just skip it. If it is a
# real error, it will be caught by concretization tests.
@@ -201,15 +200,15 @@ def test_handle_unknown_package(temporary_store, config, mock_packages):
def test_find(temporary_store, config, mock_packages):
"""Test that finding specs within an install layout works."""
layout = temporary_store.layout
- packages = list(spack.repo.path.all_packages())[:max_packages]
+ package_names = list(spack.repo.path.all_package_names())[:max_packages]
# Create install prefixes for all packages in the list
installed_specs = {}
- for pkg in packages:
- if pkg.name.startswith('external'):
+ for name in package_names:
+ if name.startswith('external'):
# External package tests cannot be installed
continue
- spec = pkg.spec.concretized()
+ spec = spack.spec.Spec(name).concretized()
installed_specs[spec.name] = spec
layout.create_install_directory(spec)
diff --git a/lib/spack/spack/test/flag_handlers.py b/lib/spack/spack/test/flag_handlers.py
index 97a0ec171c..ec197515c2 100644
--- a/lib/spack/spack/test/flag_handlers.py
+++ b/lib/spack/spack/test/flag_handlers.py
@@ -25,22 +25,18 @@ def add_o3_to_build_system_cflags(pkg, name, flags):
build_system_flags = []
if name == 'cflags':
build_system_flags.append('-O3')
- return (flags, None, build_system_flags)
+ return flags, None, build_system_flags
@pytest.mark.usefixtures('config', 'mock_packages')
class TestFlagHandlers(object):
def test_no_build_system_flags(self, temp_env):
# Test that both autotools and cmake work getting no build_system flags
- s1 = spack.spec.Spec('cmake-client')
- s1.concretize()
- pkg1 = spack.repo.get(s1)
- spack.build_environment.setup_package(pkg1, False)
+ s1 = spack.spec.Spec('cmake-client').concretized()
+ spack.build_environment.setup_package(s1.package, False)
- s2 = spack.spec.Spec('patchelf')
- s2.concretize()
- pkg2 = spack.repo.get(s2)
- spack.build_environment.setup_package(pkg2, False)
+ s2 = spack.spec.Spec('patchelf').concretized()
+ spack.build_environment.setup_package(s2.package, False)
# Use cppflags as a canary
assert 'SPACK_CPPFLAGS' not in os.environ
@@ -49,124 +45,91 @@ class TestFlagHandlers(object):
def test_unbound_method(self, temp_env):
# Other tests test flag_handlers set as bound methods and functions.
# This tests an unbound method in python2 (no change in python3).
- s = spack.spec.Spec('mpileaks cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = pkg.__class__.inject_flags
- spack.build_environment.setup_package(pkg, False)
+ s = spack.spec.Spec('mpileaks cppflags=-g').concretized()
+ s.package.flag_handler = s.package.__class__.inject_flags
+ spack.build_environment.setup_package(s.package, False)
assert os.environ['SPACK_CPPFLAGS'] == '-g'
assert 'CPPFLAGS' not in os.environ
def test_inject_flags(self, temp_env):
- s = spack.spec.Spec('mpileaks cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = inject_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('mpileaks cppflags=-g').concretized()
+ s.package.flag_handler = inject_flags
+ spack.build_environment.setup_package(s.package, False)
assert os.environ['SPACK_CPPFLAGS'] == '-g'
assert 'CPPFLAGS' not in os.environ
def test_env_flags(self, temp_env):
- s = spack.spec.Spec('mpileaks cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = env_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('mpileaks cppflags=-g').concretized()
+ s.package.flag_handler = env_flags
+ spack.build_environment.setup_package(s.package, False)
assert os.environ['CPPFLAGS'] == '-g'
assert 'SPACK_CPPFLAGS' not in os.environ
def test_build_system_flags_cmake(self, temp_env):
- s = spack.spec.Spec('cmake-client cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = build_system_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('cmake-client cppflags=-g').concretized()
+ s.package.flag_handler = build_system_flags
+ spack.build_environment.setup_package(s.package, False)
assert 'SPACK_CPPFLAGS' not in os.environ
assert 'CPPFLAGS' not in os.environ
-
- expected = set(['-DCMAKE_C_FLAGS=-g', '-DCMAKE_CXX_FLAGS=-g',
- '-DCMAKE_Fortran_FLAGS=-g'])
- assert set(pkg.cmake_flag_args) == expected
+ assert set(s.package.cmake_flag_args) == {
+ '-DCMAKE_C_FLAGS=-g', '-DCMAKE_CXX_FLAGS=-g', '-DCMAKE_Fortran_FLAGS=-g'
+ }
def test_build_system_flags_autotools(self, temp_env):
- s = spack.spec.Spec('patchelf cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = build_system_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('patchelf cppflags=-g').concretized()
+ s.package.flag_handler = build_system_flags
+ spack.build_environment.setup_package(s.package, False)
assert 'SPACK_CPPFLAGS' not in os.environ
assert 'CPPFLAGS' not in os.environ
-
- assert 'CPPFLAGS=-g' in pkg.configure_flag_args
+ assert 'CPPFLAGS=-g' in s.package.configure_flag_args
def test_build_system_flags_not_implemented(self, temp_env):
- s = spack.spec.Spec('mpileaks cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = build_system_flags
-
- # Test the command line flags method raises a NotImplementedError
+ """Test the command line flags method raises a NotImplementedError"""
+ s = spack.spec.Spec('mpileaks cppflags=-g').concretized()
+ s.package.flag_handler = build_system_flags
try:
- spack.build_environment.setup_package(pkg, False)
+ spack.build_environment.setup_package(s.package, False)
assert False
except NotImplementedError:
assert True
def test_add_build_system_flags_autotools(self, temp_env):
- s = spack.spec.Spec('patchelf cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = add_o3_to_build_system_cflags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('patchelf cppflags=-g').concretized()
+ s.package.flag_handler = add_o3_to_build_system_cflags
+ spack.build_environment.setup_package(s.package, False)
assert '-g' in os.environ['SPACK_CPPFLAGS']
assert 'CPPFLAGS' not in os.environ
-
- assert pkg.configure_flag_args == ['CFLAGS=-O3']
+ assert s.package.configure_flag_args == ['CFLAGS=-O3']
def test_add_build_system_flags_cmake(self, temp_env):
- s = spack.spec.Spec('cmake-client cppflags=-g')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = add_o3_to_build_system_cflags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('cmake-client cppflags=-g').concretized()
+ s.package.flag_handler = add_o3_to_build_system_cflags
+ spack.build_environment.setup_package(s.package, False)
assert '-g' in os.environ['SPACK_CPPFLAGS']
assert 'CPPFLAGS' not in os.environ
-
- assert pkg.cmake_flag_args == ['-DCMAKE_C_FLAGS=-O3']
+ assert s.package.cmake_flag_args == ['-DCMAKE_C_FLAGS=-O3']
def test_ld_flags_cmake(self, temp_env):
- s = spack.spec.Spec('cmake-client ldflags=-mthreads')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = build_system_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('cmake-client ldflags=-mthreads').concretized()
+ s.package.flag_handler = build_system_flags
+ spack.build_environment.setup_package(s.package, False)
assert 'SPACK_LDFLAGS' not in os.environ
assert 'LDFLAGS' not in os.environ
-
- expected = set(['-DCMAKE_EXE_LINKER_FLAGS=-mthreads',
- '-DCMAKE_MODULE_LINKER_FLAGS=-mthreads',
- '-DCMAKE_SHARED_LINKER_FLAGS=-mthreads',
- '-DCMAKE_STATIC_LINKER_FLAGS=-mthreads'])
- assert set(pkg.cmake_flag_args) == expected
+ assert set(s.package.cmake_flag_args) == {
+ '-DCMAKE_EXE_LINKER_FLAGS=-mthreads',
+ '-DCMAKE_MODULE_LINKER_FLAGS=-mthreads',
+ '-DCMAKE_SHARED_LINKER_FLAGS=-mthreads',
+ '-DCMAKE_STATIC_LINKER_FLAGS=-mthreads'
+ }
def test_ld_libs_cmake(self, temp_env):
- s = spack.spec.Spec('cmake-client ldlibs=-lfoo')
- s.concretize()
- pkg = spack.repo.get(s)
- pkg.flag_handler = build_system_flags
- spack.build_environment.setup_package(pkg, False)
-
+ s = spack.spec.Spec('cmake-client ldlibs=-lfoo').concretized()
+ s.package.flag_handler = build_system_flags
+ spack.build_environment.setup_package(s.package, False)
assert 'SPACK_LDLIBS' not in os.environ
assert 'LDLIBS' not in os.environ
-
- expected = set(['-DCMAKE_C_STANDARD_LIBRARIES=-lfoo',
- '-DCMAKE_CXX_STANDARD_LIBRARIES=-lfoo',
- '-DCMAKE_Fortran_STANDARD_LIBRARIES=-lfoo'])
- assert set(pkg.cmake_flag_args) == expected
+ assert set(s.package.cmake_flag_args) == {
+ '-DCMAKE_C_STANDARD_LIBRARIES=-lfoo',
+ '-DCMAKE_CXX_STANDARD_LIBRARIES=-lfoo',
+ '-DCMAKE_Fortran_STANDARD_LIBRARIES=-lfoo'
+ }
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index 0bf3447f83..cb3d71d5b3 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -82,8 +82,7 @@ def test_bad_git(tmpdir, mock_bad_git):
fetcher.fetch()
-@pytest.mark.parametrize("type_of_test",
- ['default', 'branch', 'tag', 'commit'])
+@pytest.mark.parametrize("type_of_test", ['default', 'branch', 'tag', 'commit'])
@pytest.mark.parametrize("secure", [True, False])
def test_fetch(type_of_test,
secure,
@@ -111,21 +110,19 @@ def test_fetch(type_of_test,
monkeypatch.delattr(pkg_class, 'git')
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- monkeypatch.setitem(pkg.versions, ver('git'), t.args)
+ s = Spec('git-test').concretized()
+ monkeypatch.setitem(s.package.versions, ver('git'), t.args)
# Enter the stage directory and check some properties
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:verify_ssl', secure):
- pkg.do_stage()
+ s.package.do_stage()
- with working_dir(pkg.stage.source_path):
+ with working_dir(s.package.stage.source_path):
assert h('HEAD') == h(t.revision)
- file_path = os.path.join(pkg.stage.source_path, t.file)
- assert os.path.isdir(pkg.stage.source_path)
+ file_path = os.path.join(s.package.stage.source_path, t.file)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
os.unlink(file_path)
@@ -134,10 +131,10 @@ def test_fetch(type_of_test,
untracked_file = 'foobarbaz'
touch(untracked_file)
assert os.path.isfile(untracked_file)
- pkg.do_restage()
+ s.package.do_restage()
assert not os.path.isfile(untracked_file)
- assert os.path.isdir(pkg.stage.source_path)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
assert h('HEAD') == h(t.revision)
@@ -163,18 +160,15 @@ def test_fetch_pkg_attr_submodule_init(
monkeypatch.setattr(pkg_class, 'git', mock_git_repository.url)
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- monkeypatch.setitem(pkg.versions, ver('git'), t.args)
-
- spec.package.do_stage()
+ s = Spec('git-test').concretized()
+ monkeypatch.setitem(s.package.versions, ver('git'), t.args)
+ s.package.do_stage()
collected_fnames = set()
- for root, dirs, files in os.walk(spec.package.stage.source_path):
+ for root, dirs, files in os.walk(s.package.stage.source_path):
collected_fnames.update(files)
# The submodules generate files with the prefix "r0_file_"
- assert set(['r0_file_0', 'r0_file_1', t.file]) < collected_fnames
+ assert {'r0_file_0', 'r0_file_1', t.file} < collected_fnames
@pytest.mark.skipif(str(spack.platforms.host()) == 'windows',
@@ -216,16 +210,14 @@ def test_debug_fetch(
t = mock_git_repository.checks[type_of_test]
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- monkeypatch.setitem(pkg.versions, ver('git'), t.args)
+ s = Spec('git-test').concretized()
+ monkeypatch.setitem(s.package.versions, ver('git'), t.args)
# Fetch then ensure source path exists
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:debug', True):
- pkg.do_fetch()
- assert os.path.isdir(pkg.stage.source_path)
+ s.package.do_fetch()
+ assert os.path.isdir(s.package.stage.source_path)
def test_git_extra_fetch(tmpdir):
@@ -261,17 +253,15 @@ def test_get_full_repo(get_full_repo, git_version, mock_git_repository,
t = mock_git_repository.checks[type_of_test]
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
+ s = Spec('git-test').concretized()
args = copy.copy(t.args)
args['get_full_repo'] = get_full_repo
- monkeypatch.setitem(pkg.versions, ver('git'), args)
+ monkeypatch.setitem(s.package.versions, ver('git'), args)
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:verify_ssl', secure):
- pkg.do_stage()
- with working_dir(pkg.stage.source_path):
+ s.package.do_stage()
+ with working_dir(s.package.stage.source_path):
branches\
= mock_git_repository.git_exe('branch', '-a',
output=str).splitlines()
@@ -308,16 +298,14 @@ def test_gitsubmodule(submodules, mock_git_repository, config,
t = mock_git_repository.checks[type_of_test]
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
+ s = Spec('git-test').concretized()
args = copy.copy(t.args)
args['submodules'] = submodules
- monkeypatch.setitem(pkg.versions, ver('git'), args)
- pkg.do_stage()
- with working_dir(pkg.stage.source_path):
+ monkeypatch.setitem(s.package.versions, ver('git'), args)
+ s.package.do_stage()
+ with working_dir(s.package.stage.source_path):
for submodule_count in range(2):
- file_path = os.path.join(pkg.stage.source_path,
+ file_path = os.path.join(s.package.stage.source_path,
'third_party/submodule{0}/r0_file_{0}'
.format(submodule_count))
if submodules:
@@ -341,18 +329,16 @@ def test_gitsubmodules_callable(
t = mock_git_repository.checks[type_of_test]
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
+ s = Spec('git-test').concretized()
args = copy.copy(t.args)
args['submodules'] = submodules_callback
- monkeypatch.setitem(pkg.versions, ver('git'), args)
- pkg.do_stage()
- with working_dir(pkg.stage.source_path):
- file_path = os.path.join(pkg.stage.source_path,
+ monkeypatch.setitem(s.package.versions, ver('git'), args)
+ s.package.do_stage()
+ with working_dir(s.package.stage.source_path):
+ file_path = os.path.join(s.package.stage.source_path,
'third_party/submodule0/r0_file_0')
assert os.path.isfile(file_path)
- file_path = os.path.join(pkg.stage.source_path,
+ file_path = os.path.join(s.package.stage.source_path,
'third_party/submodule1/r0_file_1')
assert not os.path.isfile(file_path)
@@ -368,19 +354,17 @@ def test_gitsubmodules_delete(
t = mock_git_repository.checks[type_of_test]
# Construct the package under test
- spec = Spec('git-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
+ s = Spec('git-test').concretized()
args = copy.copy(t.args)
args['submodules'] = True
args['submodules_delete'] = ['third_party/submodule0',
'third_party/submodule1']
- monkeypatch.setitem(pkg.versions, ver('git'), args)
- pkg.do_stage()
- with working_dir(pkg.stage.source_path):
- file_path = os.path.join(pkg.stage.source_path,
+ monkeypatch.setitem(s.package.versions, ver('git'), args)
+ s.package.do_stage()
+ with working_dir(s.package.stage.source_path):
+ file_path = os.path.join(s.package.stage.source_path,
'third_party/submodule0')
assert not os.path.isdir(file_path)
- file_path = os.path.join(pkg.stage.source_path,
+ file_path = os.path.join(s.package.stage.source_path,
'third_party/submodule1')
assert not os.path.isdir(file_path)
diff --git a/lib/spack/spack/test/hg_fetch.py b/lib/spack/spack/test/hg_fetch.py
index a3d84b9973..c086e5cdc9 100644
--- a/lib/spack/spack/test/hg_fetch.py
+++ b/lib/spack/spack/test/hg_fetch.py
@@ -50,21 +50,19 @@ def test_fetch(
h = mock_hg_repository.hash
# Construct the package under test
- spec = Spec('hg-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- monkeypatch.setitem(pkg.versions, ver('hg'), t.args)
+ s = Spec('hg-test').concretized()
+ monkeypatch.setitem(s.package.versions, ver('hg'), t.args)
# Enter the stage directory and check some properties
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:verify_ssl', secure):
- pkg.do_stage()
+ s.package.do_stage()
- with working_dir(pkg.stage.source_path):
+ with working_dir(s.package.stage.source_path):
assert h() == t.revision
- file_path = os.path.join(pkg.stage.source_path, t.file)
- assert os.path.isdir(pkg.stage.source_path)
+ file_path = os.path.join(s.package.stage.source_path, t.file)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
os.unlink(file_path)
@@ -73,10 +71,10 @@ def test_fetch(
untracked_file = 'foobarbaz'
touch(untracked_file)
assert os.path.isfile(untracked_file)
- pkg.do_restage()
+ s.package.do_restage()
assert not os.path.isfile(untracked_file)
- assert os.path.isdir(pkg.stage.source_path)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
assert h() == t.revision
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index c8c697fb7e..f214c340df 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -32,25 +32,32 @@ def find_nothing(*args):
def test_install_and_uninstall(install_mockery, mock_fetch, monkeypatch):
- # Get a basic concrete spec for the trivial install package.
- spec = Spec('trivial-install-test-package')
- spec.concretize()
- assert spec.concrete
+ spec = Spec('trivial-install-test-package').concretized()
- # Get the package
- pkg = spec.package
- try:
- pkg.do_install()
+ spec.package.do_install()
+ assert spec.installed
- spec._package = None
- monkeypatch.setattr(spack.repo, 'get', find_nothing)
- with pytest.raises(spack.repo.UnknownPackageError):
- spec.package
+ spec.package.do_uninstall()
+ assert not spec.installed
- pkg.do_uninstall()
- except Exception:
- pkg.remove_prefix()
- raise
+
+@pytest.mark.regression('11870')
+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()
+ assert spec.installed
+
+ # Mock deletion of the package
+ spec._package = None
+ monkeypatch.setattr(spack.repo.path, 'get', find_nothing)
+ with pytest.raises(spack.repo.UnknownPackageError):
+ spec.package
+
+ # Ensure we can uninstall it
+ PackageBase.uninstall_by_spec(spec)
+ assert not spec.installed
def test_pkg_attributes(install_mockery, mock_fetch, monkeypatch):
@@ -141,32 +148,32 @@ class MockStage(object):
def test_partial_install_delete_prefix_and_stage(install_mockery, mock_fetch):
- spec = Spec('canfail').concretized()
- pkg = spack.repo.get(spec)
- instance_rm_prefix = pkg.remove_prefix
+ s = Spec('canfail').concretized()
+
+ instance_rm_prefix = s.package.remove_prefix
try:
- pkg.succeed = False
- pkg.remove_prefix = mock_remove_prefix
+ s.package.succeed = False
+ s.package.remove_prefix = mock_remove_prefix
with pytest.raises(MockInstallError):
- pkg.do_install()
- assert os.path.isdir(pkg.prefix)
+ s.package.do_install()
+ assert os.path.isdir(s.package.prefix)
rm_prefix_checker = RemovePrefixChecker(instance_rm_prefix)
- pkg.remove_prefix = rm_prefix_checker.remove_prefix
+ s.package.remove_prefix = rm_prefix_checker.remove_prefix
# must clear failure markings for the package before re-installing it
- spack.store.db.clear_failure(spec, True)
+ spack.store.db.clear_failure(s, True)
- pkg.succeed = True
- pkg.stage = MockStage(pkg.stage)
+ s.package.succeed = True
+ s.package.stage = MockStage(s.package.stage)
- pkg.do_install(restage=True)
+ s.package.do_install(restage=True)
assert rm_prefix_checker.removed
- assert pkg.stage.test_destroyed
- assert pkg.spec.installed
+ assert s.package.stage.test_destroyed
+ assert s.package.spec.installed
finally:
- pkg.remove_prefix = instance_rm_prefix
+ s.package.remove_prefix = instance_rm_prefix
@pytest.mark.disable_clean_stage_check
@@ -178,20 +185,19 @@ def test_failing_overwrite_install_should_keep_previous_installation(
the original install prefix instead of cleaning it.
"""
# Do a successful install
- spec = Spec('canfail').concretized()
- pkg = spack.repo.get(spec)
- pkg.succeed = True
+ s = Spec('canfail').concretized()
+ s.package.succeed = True
# Do a failing overwrite install
- pkg.do_install()
- pkg.succeed = False
- kwargs = {'overwrite': [spec.dag_hash()]}
+ s.package.do_install()
+ s.package.succeed = False
+ kwargs = {'overwrite': [s.dag_hash()]}
with pytest.raises(Exception):
- pkg.do_install(**kwargs)
+ s.package.do_install(**kwargs)
- assert pkg.spec.installed
- assert os.path.exists(spec.prefix)
+ assert s.package.spec.installed
+ assert os.path.exists(s.prefix)
def test_dont_add_patches_to_installed_package(
@@ -357,42 +363,36 @@ def test_installed_upstream(install_upstream, mock_fetch):
@pytest.mark.disable_clean_stage_check
def test_partial_install_keep_prefix(install_mockery, mock_fetch, monkeypatch):
- spec = Spec('canfail').concretized()
- pkg = spack.repo.get(spec)
+ s = Spec('canfail').concretized()
- # Normally the stage should start unset, but other tests set it
- pkg._stage = None
-
- # If remove_prefix is called at any point in this test, that is an
- # error
- pkg.succeed = False # make the build fail
+ # If remove_prefix is called at any point in this test, that is an error
+ s.package.succeed = False # make the build fail
monkeypatch.setattr(spack.package_base.Package, 'remove_prefix', mock_remove_prefix)
with pytest.raises(spack.build_environment.ChildError):
- pkg.do_install(keep_prefix=True)
- assert os.path.exists(pkg.prefix)
+ s.package.do_install(keep_prefix=True)
+ assert os.path.exists(s.package.prefix)
# must clear failure markings for the package before re-installing it
- spack.store.db.clear_failure(spec, True)
+ spack.store.db.clear_failure(s, True)
- pkg.succeed = True # make the build succeed
- pkg.stage = MockStage(pkg.stage)
- pkg.do_install(keep_prefix=True)
- assert pkg.spec.installed
- assert not pkg.stage.test_destroyed
+ s.package.succeed = True # make the build succeed
+ s.package.stage = MockStage(s.package.stage)
+ s.package.do_install(keep_prefix=True)
+ assert s.package.spec.installed
+ assert not s.package.stage.test_destroyed
def test_second_install_no_overwrite_first(install_mockery, mock_fetch, monkeypatch):
- spec = Spec('canfail').concretized()
- pkg = spack.repo.get(spec)
+ s = Spec('canfail').concretized()
monkeypatch.setattr(spack.package_base.Package, 'remove_prefix', mock_remove_prefix)
- pkg.succeed = True
- pkg.do_install()
- assert pkg.spec.installed
+ s.package.succeed = True
+ s.package.do_install()
+ assert s.package.spec.installed
# If Package.install is called after this point, it will fail
- pkg.succeed = False
- pkg.do_install()
+ s.package.succeed = False
+ s.package.do_install()
def test_install_prefix_collision_fails(config, mock_fetch, mock_packages, tmpdir):
@@ -638,12 +638,13 @@ def test_log_install_with_build_files(install_mockery, monkeypatch):
def test_unconcretized_install(install_mockery, mock_fetch, mock_packages):
"""Test attempts to perform install phases with unconcretized spec."""
spec = Spec('trivial-install-test-package')
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
with pytest.raises(ValueError, match='must have a concrete spec'):
- spec.package.do_install()
+ pkg_cls(spec).do_install()
with pytest.raises(ValueError, match="only patch concrete packages"):
- spec.package.do_patch()
+ pkg_cls(spec).do_patch()
def test_install_error():
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index f228ec2d77..f2bd5e1a10 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -208,8 +208,8 @@ def test_process_binary_cache_tarball_none(install_mockery, monkeypatch,
"""Tests of _process_binary_cache_tarball when no tarball."""
monkeypatch.setattr(spack.binary_distribution, 'download_tarball', _none)
- pkg = spack.repo.get('trivial-install-test-package')
- assert not inst._process_binary_cache_tarball(pkg, None, False, False)
+ s = spack.spec.Spec('trivial-install-test-package').concretized()
+ assert not inst._process_binary_cache_tarball(s.package, None, False, False)
assert 'exists in binary cache but' in capfd.readouterr()[0]
@@ -264,26 +264,26 @@ def test_installer_str(install_mockery):
def test_check_before_phase_error(install_mockery):
- pkg = spack.repo.get('trivial-install-test-package')
- pkg.stop_before_phase = 'beforephase'
+ s = spack.spec.Spec('trivial-install-test-package').concretized()
+ s.package.stop_before_phase = 'beforephase'
with pytest.raises(inst.BadInstallPhase) as exc_info:
- inst._check_last_phase(pkg)
+ inst._check_last_phase(s.package)
err = str(exc_info.value)
assert 'is not a valid phase' in err
- assert pkg.stop_before_phase in err
+ assert s.package.stop_before_phase in err
def test_check_last_phase_error(install_mockery):
- pkg = spack.repo.get('trivial-install-test-package')
- pkg.stop_before_phase = None
- pkg.last_phase = 'badphase'
+ s = spack.spec.Spec('trivial-install-test-package').concretized()
+ s.package.stop_before_phase = None
+ s.package.last_phase = 'badphase'
with pytest.raises(inst.BadInstallPhase) as exc_info:
- inst._check_last_phase(pkg)
+ inst._check_last_phase(s.package)
err = str(exc_info.value)
assert 'is not a valid phase' in err
- assert pkg.last_phase in err
+ assert s.package.last_phase in err
def test_installer_ensure_ready_errors(install_mockery, monkeypatch):
@@ -414,9 +414,10 @@ def test_ensure_locked_new_warn(install_mockery, monkeypatch, tmpdir, capsys):
def test_package_id_err(install_mockery):
- pkg = spack.repo.get('trivial-install-test-package')
+ s = spack.spec.Spec('trivial-install-test-package')
+ pkg_cls = spack.repo.path.get_pkg_class(s.name)
with pytest.raises(ValueError, match='spec is not concretized'):
- inst.package_id(pkg)
+ inst.package_id(pkg_cls(s))
def test_package_id_ok(install_mockery):
@@ -447,8 +448,12 @@ def test_packages_needed_to_bootstrap_compiler_none(install_mockery):
assert not packages
-def test_packages_needed_to_bootstrap_compiler_packages(install_mockery,
- monkeypatch):
+@pytest.mark.xfail(
+ reason="fails when assuming Spec.package can only be called on concrete specs"
+)
+def test_packages_needed_to_bootstrap_compiler_packages(
+ install_mockery, monkeypatch
+):
spec = spack.spec.Spec('trivial-install-test-package')
spec.concretize()
diff --git a/lib/spack/spack/test/mirror.py b/lib/spack/spack/test/mirror.py
index 3f02239b61..9dc1856958 100644
--- a/lib/spack/spack/test/mirror.py
+++ b/lib/spack/spack/test/mirror.py
@@ -39,18 +39,14 @@ def set_up_package(name, repository, url_attr):
2. Point the package's version args at that repo.
"""
# Set up packages to point at mock repos.
- spec = Spec(name)
- spec.concretize()
- # Get the package and fix its fetch args to point to a mock repo
- pkg = spack.repo.get(spec)
-
+ s = Spec(name).concretized()
repos[name] = repository
# change the fetch args of the first (only) version.
- assert len(pkg.versions) == 1
- v = next(iter(pkg.versions))
+ assert len(s.package.versions) == 1
- pkg.versions[v][url_attr] = repository.url
+ v = next(iter(s.package.versions))
+ s.package.versions[v][url_attr] = repository.url
def check_mirror():
@@ -249,7 +245,7 @@ def test_invalid_json_mirror_collection(invalid_json, error_message):
def test_mirror_archive_paths_no_version(mock_packages, config, mock_archive):
- spec = Spec('trivial-install-test-package@nonexistingversion')
+ spec = Spec('trivial-install-test-package@nonexistingversion').concretized()
fetcher = spack.fetch_strategy.URLFetchStrategy(mock_archive.url)
spack.mirror.mirror_archive_paths(fetcher, 'per-package-ref', spec)
diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py
index 9eff0c23cc..4031de98d1 100644
--- a/lib/spack/spack/test/modules/common.py
+++ b/lib/spack/spack/test/modules/common.py
@@ -10,6 +10,7 @@ import pytest
import spack.error
import spack.modules.tcl
+import spack.package_base
import spack.spec
from spack.modules.common import UpstreamModuleIndex
from spack.spec import Spec
@@ -203,31 +204,25 @@ module_index:
spack.modules.common.upstream_module_index = old_index
-def test_load_installed_package_not_in_repo(install_mockery, mock_fetch,
- monkeypatch):
- # Get a basic concrete spec for the trivial install package.
- spec = Spec('trivial-install-test-package')
- spec.concretize()
- assert spec.concrete
-
- # Get the package
- pkg = spec.package
+@pytest.mark.regression('14347')
+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()
def find_nothing(*args):
raise spack.repo.UnknownPackageError(
'Repo package access is disabled for test')
- try:
- pkg.do_install()
-
- spec._package = None
- monkeypatch.setattr(spack.repo, 'get', find_nothing)
- with pytest.raises(spack.repo.UnknownPackageError):
- spec.package
-
- module_path = spack.modules.common.get_module('tcl', spec, True)
- assert module_path
- pkg.do_uninstall()
- except Exception:
- pkg.remove_prefix()
- raise
+ # Mock deletion of the package
+ spec._package = None
+ monkeypatch.setattr(spack.repo.path, 'get', find_nothing)
+ with pytest.raises(spack.repo.UnknownPackageError):
+ spec.package
+
+ module_path = spack.modules.common.get_module('tcl', spec, True)
+ assert module_path
+
+ spack.package_base.PackageBase.uninstall_by_spec(spec)
diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py
index 4677a412bf..1e0cee71c7 100644
--- a/lib/spack/spack/test/multimethod.py
+++ b/lib/spack/spack/test/multimethod.py
@@ -4,13 +4,23 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""Test for multi_method dispatch."""
+import os
+import sys
+
import pytest
import spack.platforms
import spack.repo
+import spack.spec
from spack.multimethod import NoSuchMethodError
-pytestmark = pytest.mark.usefixtures('mock_packages')
+pytestmark = [
+ pytest.mark.usefixtures('mock_packages', 'config'),
+ pytest.mark.skipif(
+ os.environ.get('SPACK_TEST_SOLVER') == 'original' or sys.platform == 'win32',
+ reason='The original concretizer cannot concretize most of the specs'
+ )
+]
@pytest.fixture(scope='module',
@@ -25,142 +35,81 @@ def pkg_name(request):
def test_no_version_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '@2.0')
+ spec = spack.spec.Spec(pkg_name + '@2.0').concretized()
with pytest.raises(NoSuchMethodError):
- pkg.no_version_2()
-
-
-def test_one_version_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '@1.0')
- assert pkg.no_version_2() == 1
-
- pkg = spack.repo.get(pkg_name + '@3.0')
- assert pkg.no_version_2() == 3
-
- pkg = spack.repo.get(pkg_name + '@4.0')
- assert pkg.no_version_2() == 4
-
-
-def test_version_overlap(pkg_name):
- pkg = spack.repo.get(pkg_name + '@2.0')
- assert pkg.version_overlap() == 1
-
- pkg = spack.repo.get(pkg_name + '@5.0')
- assert pkg.version_overlap() == 2
-
-
-def test_mpi_version(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich@3.0.4')
- assert pkg.mpi_version() == 3
-
- pkg = spack.repo.get(pkg_name + '^mpich2@1.2')
- assert pkg.mpi_version() == 2
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.0')
- assert pkg.mpi_version() == 1
-
-
-def test_undefined_mpi_version(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich@0.4')
- assert pkg.mpi_version() == 1
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.4')
- assert pkg.mpi_version() == 1
-
-
-def test_default_works(pkg_name):
- pkg = spack.repo.get(pkg_name + '%gcc')
- assert pkg.has_a_default() == 'gcc'
-
- pkg = spack.repo.get(pkg_name + '%intel')
- assert pkg.has_a_default() == 'intel'
-
- pkg = spack.repo.get(pkg_name + '%pgi')
- assert pkg.has_a_default() == 'default'
+ spec.package.no_version_2()
+
+
+@pytest.mark.parametrize('constraint_str,method_name,expected_result', [
+ # Only one version match these constraints
+ ('@1.0', 'no_version_2', 1),
+ ('@3.0', 'no_version_2', 3),
+ ('@4.0', 'no_version_2', 4),
+ # These constraints overlap, in which case the first match wins
+ ('@2.0', 'version_overlap', 1),
+ ('@5.0', 'version_overlap', 2),
+ # These constraints are on the version of a virtual dependency
+ ('^mpich@3.0.4', 'mpi_version', 3),
+ ('^mpich2@1.2', 'mpi_version', 2),
+ ('^mpich@1.0', 'mpi_version', 1),
+ # Undefined mpi versions
+ ('^mpich@0.4', 'mpi_version', 1),
+ ('^mpich@1.4', 'mpi_version', 1),
+ # Constraints on compilers with a default
+ ('%gcc', 'has_a_default', 'gcc'),
+ ('%clang', 'has_a_default', 'clang'),
+ ('%apple-clang os=elcapitan', 'has_a_default', 'default'),
+ # Constraints on dependencies
+ ('^zmpi', 'different_by_dep', 'zmpi'),
+ ('^mpich', 'different_by_dep', 'mpich'),
+ # Constraints on virtual dependencies
+ ('^mpich2', 'different_by_virtual_dep', 2),
+ ('^mpich@1.0', 'different_by_virtual_dep', 1),
+ # Multimethod with base classes
+ ('@1', 'base_method', 'base_method'),
+ # Boolean
+ ('', 'boolean_true_first', 'True'),
+ ('', 'boolean_false_first', 'True')
+])
+def test_multimethod_calls(pkg_name, constraint_str, method_name, expected_result):
+ s = spack.spec.Spec(pkg_name + constraint_str).concretized()
+ msg = "Method {0} from {1} is giving a wrong result".format(method_name, s)
+ assert getattr(s.package, method_name)() == expected_result, msg
def test_target_match(pkg_name):
platform = spack.platforms.host()
targets = list(platform.targets.values())
for target in targets[:-1]:
- pkg = spack.repo.get(pkg_name + ' target=' + target.name)
- assert pkg.different_by_target() == target.name
+ s = spack.spec.Spec(pkg_name + ' target=' + target.name).concretized()
+ assert s.package.different_by_target() == target.name
- pkg = spack.repo.get(pkg_name + ' target=' + targets[-1].name)
+ s = spack.spec.Spec(pkg_name + ' target=' + targets[-1].name).concretized()
if len(targets) == 1:
- assert pkg.different_by_target() == targets[-1].name
+ assert s.package.different_by_target() == targets[-1].name
else:
with pytest.raises(NoSuchMethodError):
- pkg.different_by_target()
-
-
-def test_dependency_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '^zmpi')
- assert pkg.different_by_dep() == 'zmpi'
-
- pkg = spack.repo.get(pkg_name + '^mpich')
- assert pkg.different_by_dep() == 'mpich'
-
- # If we try to switch on some entirely different dep, it's ambiguous,
- # but should take the first option
- pkg = spack.repo.get(pkg_name + '^foobar')
- assert pkg.different_by_dep() == 'mpich'
-
-
-def test_virtual_dep_match(pkg_name):
- pkg = spack.repo.get(pkg_name + '^mpich2')
- assert pkg.different_by_virtual_dep() == 2
-
- pkg = spack.repo.get(pkg_name + '^mpich@1.0')
- assert pkg.different_by_virtual_dep() == 1
-
-
-def test_multimethod_with_base_class(pkg_name):
- pkg = spack.repo.get(pkg_name + '@3')
- assert pkg.base_method() == pkg.spec.name
-
- pkg = spack.repo.get(pkg_name + '@1')
- assert pkg.base_method() == "base_method"
-
-
-def test_multimethod_inherited_and_overridden():
- pkg = spack.repo.get('multimethod-inheritor@1.0')
- assert pkg.inherited_and_overridden() == 'inheritor@1.0'
-
- pkg = spack.repo.get('multimethod-inheritor@2.0')
- assert pkg.inherited_and_overridden() == 'base@2.0'
-
- pkg = spack.repo.get('multimethod@1.0')
- assert pkg.inherited_and_overridden() == 'base@1.0'
-
- pkg = spack.repo.get('multimethod@2.0')
- assert pkg.inherited_and_overridden() == 'base@2.0'
-
-
-def test_multimethod_diamond_inheritance():
- pkg = spack.repo.get('multimethod-diamond@1.0')
- assert pkg.diamond_inheritance() == 'base_package'
-
- pkg = spack.repo.get('multimethod-base@1.0')
- assert pkg.diamond_inheritance() == 'base_package'
-
- pkg = spack.repo.get('multimethod-diamond@2.0')
- assert pkg.diamond_inheritance() == 'first_parent'
-
- pkg = spack.repo.get('multimethod-inheritor@2.0')
- assert pkg.diamond_inheritance() == 'first_parent'
-
- pkg = spack.repo.get('multimethod-diamond@3.0')
- assert pkg.diamond_inheritance() == 'second_parent'
-
- pkg = spack.repo.get('multimethod-diamond-parent@3.0')
- assert pkg.diamond_inheritance() == 'second_parent'
-
- pkg = spack.repo.get('multimethod-diamond@4.0')
- assert pkg.diamond_inheritance() == 'subclass'
-
-
-def test_multimethod_boolean(pkg_name):
- pkg = spack.repo.get(pkg_name)
- assert pkg.boolean_true_first() == 'True'
- assert pkg.boolean_false_first() == 'True'
+ s.package.different_by_target()
+
+
+@pytest.mark.parametrize('spec_str,method_name,expected_result', [
+ # This is overridden in the second case
+ ('multimethod@3', 'base_method', 'multimethod'),
+ ('multimethod-inheritor@3', 'base_method', 'multimethod-inheritor'),
+ # Here we have a mix of inherited and overridden methods
+ ('multimethod-inheritor@1.0', 'inherited_and_overridden', 'inheritor@1.0'),
+ ('multimethod-inheritor@2.0', 'inherited_and_overridden', 'base@2.0'),
+ ('multimethod@1.0', 'inherited_and_overridden', 'base@1.0'),
+ ('multimethod@2.0', 'inherited_and_overridden', 'base@2.0'),
+ # Diamond-like inheritance (even though the MRO linearize everything)
+ ('multimethod-diamond@1.0', 'diamond_inheritance', 'base_package'),
+ ('multimethod-base@1.0', 'diamond_inheritance', 'base_package'),
+ ('multimethod-diamond@2.0', 'diamond_inheritance', 'first_parent'),
+ ('multimethod-inheritor@2.0', 'diamond_inheritance', 'first_parent'),
+ ('multimethod-diamond@3.0', 'diamond_inheritance', 'second_parent'),
+ ('multimethod-diamond-parent@3.0', 'diamond_inheritance', 'second_parent'),
+ ('multimethod-diamond@4.0', 'diamond_inheritance', 'subclass'),
+])
+def test_multimethod_calls_and_inheritance(spec_str, method_name, expected_result):
+ s = spack.spec.Spec(spec_str).concretized()
+ assert getattr(s.package, method_name)() == expected_result
diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py
index 909cf4193f..15fd1237fb 100644
--- a/lib/spack/spack/test/package_class.py
+++ b/lib/spack/spack/test/package_class.py
@@ -45,35 +45,32 @@ def mpileaks_possible_deps(mock_packages, mpi_names):
def test_possible_dependencies(mock_packages, mpileaks_possible_deps):
- mpileaks = spack.repo.get('mpileaks')
- assert mpileaks_possible_deps == (
- mpileaks.possible_dependencies(expand_virtuals=True))
-
+ pkg_cls = spack.repo.path.get_pkg_class('mpileaks')
+ expanded_possible_deps = pkg_cls.possible_dependencies(expand_virtuals=True)
+ assert mpileaks_possible_deps == expanded_possible_deps
assert {
- 'callpath': set(['dyninst', 'mpi']),
- 'dyninst': set(['libdwarf', 'libelf']),
- 'libdwarf': set(['libelf']),
+ 'callpath': {'dyninst', 'mpi'},
+ 'dyninst': {'libdwarf', 'libelf'},
+ 'libdwarf': {'libelf'},
'libelf': set(),
'mpi': set(),
- 'mpileaks': set(['callpath', 'mpi']),
- } == mpileaks.possible_dependencies(expand_virtuals=False)
+ 'mpileaks': {'callpath', 'mpi'},
+ } == pkg_cls.possible_dependencies(expand_virtuals=False)
def test_possible_direct_dependencies(mock_packages, mpileaks_possible_deps):
- mpileaks = spack.repo.get('mpileaks')
- deps = mpileaks.possible_dependencies(transitive=False,
- expand_virtuals=False)
-
+ pkg_cls = spack.repo.path.get_pkg_class('mpileaks')
+ deps = pkg_cls.possible_dependencies(transitive=False, expand_virtuals=False)
assert {
'callpath': set(),
'mpi': set(),
- 'mpileaks': set(['callpath', 'mpi']),
+ 'mpileaks': {'callpath', 'mpi'},
} == deps
def test_possible_dependencies_virtual(mock_packages, mpi_names):
expected = dict(
- (name, set(spack.repo.get(name).dependencies))
+ (name, set(spack.repo.path.get_pkg_class(name).dependencies))
for name in mpi_names
)
@@ -85,31 +82,29 @@ def test_possible_dependencies_virtual(mock_packages, mpi_names):
def test_possible_dependencies_missing(mock_packages):
- md = spack.repo.get("missing-dependency")
+ pkg_cls = spack.repo.path.get_pkg_class("missing-dependency")
missing = {}
- md.possible_dependencies(transitive=True, missing=missing)
- assert set([
- "this-is-a-missing-dependency"
- ]) == missing["missing-dependency"]
+ pkg_cls.possible_dependencies(transitive=True, missing=missing)
+ assert {"this-is-a-missing-dependency"} == missing["missing-dependency"]
def test_possible_dependencies_with_deptypes(mock_packages):
- dtbuild1 = spack.repo.get('dtbuild1')
+ dtbuild1 = spack.repo.path.get_pkg_class('dtbuild1')
assert {
- 'dtbuild1': set(['dtrun2', 'dtlink2']),
+ 'dtbuild1': {'dtrun2', 'dtlink2'},
'dtlink2': set(),
'dtrun2': set(),
} == dtbuild1.possible_dependencies(deptype=('link', 'run'))
assert {
- 'dtbuild1': set(['dtbuild2', 'dtlink2']),
+ 'dtbuild1': {'dtbuild2', 'dtlink2'},
'dtbuild2': set(),
'dtlink2': set(),
} == dtbuild1.possible_dependencies(deptype=('build'))
assert {
- 'dtbuild1': set(['dtlink2']),
+ 'dtbuild1': {'dtlink2'},
'dtlink2': set(),
} == dtbuild1.possible_dependencies(deptype=('link'))
@@ -159,27 +154,26 @@ def setup_install_test(source_paths, install_test_root):
])
def test_cache_extra_sources(install_mockery, spec, sources, extras, expect):
"""Test the package's cache extra test sources helper function."""
+ s = spack.spec.Spec(spec).concretized()
+ s.package.spec.concretize()
+ source_path = s.package.stage.source_path
- pkg = spack.repo.get(spec)
- pkg.spec.concretize()
- source_path = pkg.stage.source_path
-
- srcs = [fs.join_path(source_path, s) for s in sources]
- setup_install_test(srcs, pkg.install_test_root)
+ srcs = [fs.join_path(source_path, src) for src in sources]
+ setup_install_test(srcs, s.package.install_test_root)
emsg_dir = 'Expected {0} to be a directory'
emsg_file = 'Expected {0} to be a file'
- for s in srcs:
- assert os.path.exists(s), 'Expected {0} to exist'.format(s)
- if os.path.splitext(s)[1]:
- assert os.path.isfile(s), emsg_file.format(s)
+ for src in srcs:
+ assert os.path.exists(src), 'Expected {0} to exist'.format(src)
+ if os.path.splitext(src)[1]:
+ assert os.path.isfile(src), emsg_file.format(src)
else:
- assert os.path.isdir(s), emsg_dir.format(s)
+ assert os.path.isdir(src), emsg_dir.format(src)
- pkg.cache_extra_test_sources(extras)
+ s.package.cache_extra_test_sources(extras)
- src_dests = [fs.join_path(pkg.install_test_root, s) for s in sources]
- exp_dests = [fs.join_path(pkg.install_test_root, e) for e in expect]
+ src_dests = [fs.join_path(s.package.install_test_root, src) for src in sources]
+ exp_dests = [fs.join_path(s.package.install_test_root, e) for e in expect]
poss_dests = set(src_dests) | set(exp_dests)
msg = 'Expected {0} to{1} exist'
diff --git a/lib/spack/spack/test/package_sanity.py b/lib/spack/spack/test/package_sanity.py
index dabe768b37..145ece1f7e 100644
--- a/lib/spack/spack/test/package_sanity.py
+++ b/lib/spack/spack/test/package_sanity.py
@@ -19,6 +19,7 @@ import spack.fetch_strategy
import spack.package_base
import spack.paths
import spack.repo
+import spack.spec
import spack.util.crypto as crypto
import spack.util.executable as executable
import spack.util.package_hash as ph
@@ -28,7 +29,7 @@ import spack.variant
def check_repo():
"""Get all packages in the builtin repo to make sure they work."""
for name in spack.repo.all_package_names():
- spack.repo.get(name)
+ spack.repo.path.get_pkg_class(name)
@pytest.mark.maybeslow
@@ -40,7 +41,8 @@ def test_get_all_packages():
def test_packages_are_pickleable():
failed_to_pickle = list()
for name in spack.repo.all_package_names():
- pkg = spack.repo.get(name)
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ pkg = pkg_cls(spack.spec.Spec(name))
try:
pickle.dumps(pkg)
except Exception:
@@ -54,7 +56,8 @@ def test_packages_are_pickleable():
', '.join(failed_to_pickle))
for name in failed_to_pickle:
- pkg = spack.repo.get(name)
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ pkg = pkg_cls(spack.spec.Spec(name))
pickle.dumps(pkg)
@@ -91,12 +94,9 @@ def test_repo_getpkg_names_and_classes():
print(names)
classes = spack.repo.path.all_package_classes()
print(list(classes))
- pkgs = spack.repo.path.all_packages()
- print(list(pkgs))
- for name, cls, pkg in zip(names, classes, pkgs):
+ for name, cls in zip(names, classes):
assert cls.name == name
- assert pkg.name == name
def test_get_all_mock_packages():
@@ -132,7 +132,8 @@ def test_all_virtual_packages_have_default_providers():
def test_package_version_consistency():
"""Make sure all versions on builtin packages produce a fetcher."""
for name in spack.repo.all_package_names():
- pkg = spack.repo.get(name)
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ pkg = pkg_cls(spack.spec.Spec(name))
spack.fetch_strategy.check_pkg_attributes(pkg)
for version in pkg.versions:
assert spack.fetch_strategy.for_package_version(pkg, version)
@@ -164,10 +165,9 @@ def test_no_fixme():
def test_docstring():
"""Ensure that every package has a docstring."""
-
for name in spack.repo.all_package_names():
- pkg = spack.repo.get(name)
- assert pkg.__doc__
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ assert pkg_cls.__doc__
def test_all_packages_use_sha256_checksums():
@@ -175,7 +175,8 @@ def test_all_packages_use_sha256_checksums():
errors = []
for name in spack.repo.all_package_names():
- pkg = spack.repo.path.get(name)
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ pkg = pkg_cls(spack.spec.Spec(name))
# for now, don't enforce on packages that require manual downloads
# TODO: eventually fix these, too.
@@ -214,11 +215,11 @@ def test_api_for_build_and_run_environment():
run environment, and not the old one.
"""
failing = []
- for pkg in spack.repo.path.all_packages():
- add_to_list = (hasattr(pkg, 'setup_environment') or
- hasattr(pkg, 'setup_dependent_environment'))
+ for pkg_cls in spack.repo.path.all_package_classes():
+ add_to_list = (hasattr(pkg_cls, 'setup_environment') or
+ hasattr(pkg_cls, 'setup_dependent_environment'))
if add_to_list:
- failing.append(pkg)
+ failing.append(pkg_cls)
msg = ('there are {0} packages using the old API to set build '
'and run environment [{1}], for further information see '
@@ -246,7 +247,8 @@ def test_prs_update_old_api():
for file in changed_package_files:
if 'builtin.mock' not in file: # don't restrict packages for tests
name = os.path.basename(os.path.dirname(file))
- pkg = spack.repo.get(name)
+ pkg_cls = spack.repo.path.get_pkg_class(name)
+ pkg = pkg_cls(spack.spec.Spec(name))
failed = (hasattr(pkg, 'setup_environment') or
hasattr(pkg, 'setup_dependent_environment'))
@@ -279,8 +281,8 @@ def test_all_dependencies_exist():
def test_variant_defaults_are_parsable_from_cli():
"""Ensures that variant defaults are parsable from cli."""
failing = []
- for pkg in spack.repo.path.all_packages():
- for variant_name, entry in pkg.variants.items():
+ for pkg_cls in spack.repo.path.all_package_classes():
+ for variant_name, entry in pkg_cls.variants.items():
variant, _ = entry
default_is_parsable = (
# Permitting a default that is an instance on 'int' permits
@@ -289,18 +291,18 @@ def test_variant_defaults_are_parsable_from_cli():
isinstance(variant.default, int) or variant.default
)
if not default_is_parsable:
- failing.append((pkg.name, variant_name))
+ failing.append((pkg_cls.name, variant_name))
assert not failing
def test_variant_defaults_listed_explicitly_in_values():
failing = []
- for pkg in spack.repo.path.all_packages():
- for variant_name, entry in pkg.variants.items():
+ for pkg_cls in spack.repo.path.all_package_classes():
+ for variant_name, entry in pkg_cls.variants.items():
variant, _ = entry
vspec = variant.make_default()
try:
- variant.validate_or_raise(vspec, pkg=pkg)
+ variant.validate_or_raise(vspec, pkg_cls=pkg_cls)
except spack.variant.InvalidVariantValueError:
- failing.append((pkg.name, variant.name))
+ failing.append((pkg_cls.name, variant.name))
assert not failing
diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py
index 5d2928115e..0c02eae5a6 100644
--- a/lib/spack/spack/test/packages.py
+++ b/lib/spack/spack/test/packages.py
@@ -19,11 +19,11 @@ from spack.version import VersionChecksumError
@pytest.mark.usefixtures('config', 'mock_packages')
class TestPackage(object):
def test_load_package(self):
- spack.repo.get('mpich')
+ spack.repo.path.get_pkg_class('mpich')
def test_package_name(self):
- pkg = spack.repo.get('mpich')
- assert pkg.name == 'mpich'
+ pkg_cls = spack.repo.path.get_pkg_class('mpich')
+ assert pkg_cls.name == 'mpich'
def test_package_filename(self):
repo = spack.repo.Repo(mock_packages_path)
@@ -64,25 +64,23 @@ class TestPackage(object):
from spack.pkg.builtin import mock # noqa
def test_inheritance_of_diretives(self):
- p = spack.repo.get('simple-inheritance')
+ pkg_cls = spack.repo.path.get_pkg_class('simple-inheritance')
# Check dictionaries that should have been filled by directives
- assert len(p.dependencies) == 3
- assert 'cmake' in p.dependencies
- assert 'openblas' in p.dependencies
- assert 'mpi' in p.dependencies
- assert len(p.provided) == 2
+ assert len(pkg_cls.dependencies) == 3
+ assert 'cmake' in pkg_cls.dependencies
+ assert 'openblas' in pkg_cls.dependencies
+ assert 'mpi' in pkg_cls.dependencies
+ assert len(pkg_cls.provided) == 2
# Check that Spec instantiation behaves as we expect
- s = Spec('simple-inheritance')
- s.concretize()
+ s = Spec('simple-inheritance').concretized()
assert '^cmake' in s
assert '^openblas' in s
assert '+openblas' in s
assert 'mpi' in s
- s = Spec('simple-inheritance~openblas')
- s.concretize()
+ s = Spec('simple-inheritance~openblas').concretized()
assert '^cmake' in s
assert '^openblas' not in s
assert '~openblas' in s
@@ -134,197 +132,122 @@ def test_urls_for_versions(mock_packages, config):
def test_url_for_version_with_no_urls(mock_packages, config):
- pkg = spack.repo.get('git-test')
+ spec = Spec('git-test')
+ pkg_cls = spack.repo.path.get_pkg_class(spec.name)
with pytest.raises(spack.package_base.NoURLError):
- pkg.url_for_version('1.0')
+ pkg_cls(spec).url_for_version('1.0')
with pytest.raises(spack.package_base.NoURLError):
- pkg.url_for_version('1.1')
+ pkg_cls(spec).url_for_version('1.1')
def test_url_for_version_with_only_overrides(mock_packages, config):
- spec = Spec('url-only-override')
- spec.concretize()
-
- pkg = spack.repo.get(spec)
+ s = Spec('url-only-override').concretized()
# these exist and should just take the URL provided in the package
- assert pkg.url_for_version('1.0.0') == 'http://a.example.com/url_override-1.0.0.tar.gz'
- assert pkg.url_for_version('0.9.0') == 'http://b.example.com/url_override-0.9.0.tar.gz'
- assert pkg.url_for_version('0.8.1') == 'http://c.example.com/url_override-0.8.1.tar.gz'
+ assert s.package.url_for_version('1.0.0') == 'http://a.example.com/url_override-1.0.0.tar.gz'
+ assert s.package.url_for_version('0.9.0') == 'http://b.example.com/url_override-0.9.0.tar.gz'
+ assert s.package.url_for_version('0.8.1') == 'http://c.example.com/url_override-0.8.1.tar.gz'
# these don't exist but should still work, even if there are only overrides
- assert pkg.url_for_version('1.0.5') == 'http://a.example.com/url_override-1.0.5.tar.gz'
- assert pkg.url_for_version('0.9.5') == 'http://b.example.com/url_override-0.9.5.tar.gz'
- assert pkg.url_for_version('0.8.5') == 'http://c.example.com/url_override-0.8.5.tar.gz'
- assert pkg.url_for_version('0.7.0') == 'http://c.example.com/url_override-0.7.0.tar.gz'
+ assert s.package.url_for_version('1.0.5') == 'http://a.example.com/url_override-1.0.5.tar.gz'
+ assert s.package.url_for_version('0.9.5') == 'http://b.example.com/url_override-0.9.5.tar.gz'
+ assert s.package.url_for_version('0.8.5') == 'http://c.example.com/url_override-0.8.5.tar.gz'
+ assert s.package.url_for_version('0.7.0') == 'http://c.example.com/url_override-0.7.0.tar.gz'
def test_url_for_version_with_only_overrides_with_gaps(mock_packages, config):
- spec = Spec('url-only-override-with-gaps')
- spec.concretize()
-
- pkg = spack.repo.get(spec)
+ s = Spec('url-only-override-with-gaps').concretized()
# same as for url-only-override -- these are specific
- assert pkg.url_for_version('1.0.0') == 'http://a.example.com/url_override-1.0.0.tar.gz'
- assert pkg.url_for_version('0.9.0') == 'http://b.example.com/url_override-0.9.0.tar.gz'
- assert pkg.url_for_version('0.8.1') == 'http://c.example.com/url_override-0.8.1.tar.gz'
+ assert s.package.url_for_version('1.0.0') == 'http://a.example.com/url_override-1.0.0.tar.gz'
+ assert s.package.url_for_version('0.9.0') == 'http://b.example.com/url_override-0.9.0.tar.gz'
+ assert s.package.url_for_version('0.8.1') == 'http://c.example.com/url_override-0.8.1.tar.gz'
# these don't have specific URLs, but should still work by extrapolation
- assert pkg.url_for_version('1.0.5') == 'http://a.example.com/url_override-1.0.5.tar.gz'
- assert pkg.url_for_version('0.9.5') == 'http://b.example.com/url_override-0.9.5.tar.gz'
- assert pkg.url_for_version('0.8.5') == 'http://c.example.com/url_override-0.8.5.tar.gz'
- assert pkg.url_for_version('0.7.0') == 'http://c.example.com/url_override-0.7.0.tar.gz'
-
-
-def test_git_top_level(mock_packages, config):
+ assert s.package.url_for_version('1.0.5') == 'http://a.example.com/url_override-1.0.5.tar.gz'
+ assert s.package.url_for_version('0.9.5') == 'http://b.example.com/url_override-0.9.5.tar.gz'
+ assert s.package.url_for_version('0.8.5') == 'http://c.example.com/url_override-0.8.5.tar.gz'
+ assert s.package.url_for_version('0.7.0') == 'http://c.example.com/url_override-0.7.0.tar.gz'
+
+
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('spec_str,expected_type,expected_url', [
+ ('git-top-level', spack.fetch_strategy.GitFetchStrategy, 'https://example.com/some/git/repo'),
+ ('svn-top-level', spack.fetch_strategy.SvnFetchStrategy, 'https://example.com/some/svn/repo'),
+ ('hg-top-level', spack.fetch_strategy.HgFetchStrategy, 'https://example.com/some/hg/repo'),
+])
+def test_fetcher_url(spec_str, expected_type, expected_url):
"""Ensure that top-level git attribute can be used as a default."""
- pkg = spack.repo.get('git-top-level')
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.0')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
-
-
-def test_svn_top_level(mock_packages, config):
- """Ensure that top-level svn attribute can be used as a default."""
- pkg = spack.repo.get('svn-top-level')
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.0')
- assert isinstance(fetcher, spack.fetch_strategy.SvnFetchStrategy)
- assert fetcher.url == 'https://example.com/some/svn/repo'
-
-
-def test_hg_top_level(mock_packages, config):
- """Ensure that top-level hg attribute can be used as a default."""
- pkg = spack.repo.get('hg-top-level')
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.0')
- assert isinstance(fetcher, spack.fetch_strategy.HgFetchStrategy)
- assert fetcher.url == 'https://example.com/some/hg/repo'
-
-
-def test_no_extrapolate_without_url(mock_packages, config):
+ s = Spec(spec_str).concretized()
+ fetcher = spack.fetch_strategy.for_package_version(s.package, '1.0')
+ assert isinstance(fetcher, expected_type)
+ assert fetcher.url == expected_url
+
+
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('spec_str,version_str,exception_type', [
+ # Non-url-package
+ ('git-top-level', '1.1', spack.fetch_strategy.ExtrapolationError),
+ # Two VCS specified together
+ ('git-url-svn-top-level', '1.0', spack.fetch_strategy.FetcherConflict),
+ ('git-svn-top-level', '1.0', spack.fetch_strategy.FetcherConflict),
+])
+def test_fetcher_errors(spec_str, version_str, exception_type):
"""Verify that we can't extrapolate versions for non-URL packages."""
- pkg = spack.repo.get('git-top-level')
-
- with pytest.raises(spack.fetch_strategy.ExtrapolationError):
- spack.fetch_strategy.for_package_version(pkg, '1.1')
-
-
-def test_two_vcs_fetchers_top_level(mock_packages, config):
- """Verify conflict when two VCS strategies are specified together."""
-
- pkg = spack.repo.get('git-url-svn-top-level')
- with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.0')
-
- pkg = spack.repo.get('git-svn-top-level')
- with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.0')
+ with pytest.raises(exception_type):
+ s = Spec(spec_str).concretized()
+ spack.fetch_strategy.for_package_version(s.package, version_str)
-def test_git_url_top_level_url_versions(mock_packages, config):
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('version_str,expected_url,digest', [
+ ('2.0', 'https://example.com/some/tarball-2.0.tar.gz', '20'),
+ ('2.1', 'https://example.com/some/tarball-2.1.tar.gz', '21'),
+ ('2.2', 'https://www.example.com/foo2.2.tar.gz', '22'),
+ ('2.3', 'https://www.example.com/foo2.3.tar.gz', '23'),
+])
+def test_git_url_top_level_url_versions(version_str, expected_url, digest):
"""Test URL fetch strategy inference when url is specified with git."""
-
- pkg = spack.repo.get('git-url-top-level')
-
+ s = Spec('git-url-top-level').concretized()
# leading 62 zeros of sha256 hash
leading_zeros = '0' * 62
- fetcher = spack.fetch_strategy.for_package_version(pkg, '2.0')
- assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.url == 'https://example.com/some/tarball-2.0.tar.gz'
- assert fetcher.digest == leading_zeros + '20'
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '2.1')
- assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.url == 'https://example.com/some/tarball-2.1.tar.gz'
- assert fetcher.digest == leading_zeros + '21'
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '2.2')
- assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.url == 'https://www.example.com/foo2.2.tar.gz'
- assert fetcher.digest == leading_zeros + '22'
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '2.3')
+ fetcher = spack.fetch_strategy.for_package_version(s.package, version_str)
assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.url == 'https://www.example.com/foo2.3.tar.gz'
- assert fetcher.digest == leading_zeros + '23'
-
-
-def test_git_url_top_level_git_versions(mock_packages, config):
+ assert fetcher.url == expected_url
+ assert fetcher.digest == leading_zeros + digest
+
+
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('version_str,tag,commit,branch', [
+ ('3.0', 'v3.0', None, None),
+ ('3.1', 'v3.1', 'abc31', None),
+ ('3.2', None, None, 'releases/v3.2'),
+ ('3.3', None, 'abc33', 'releases/v3.3'),
+ ('3.4', None, 'abc34', None),
+ ('submodules', None, None, None),
+ ('develop', None, None, 'develop'),
+])
+def test_git_url_top_level_git_versions(version_str, tag, commit, branch):
"""Test git fetch strategy inference when url is specified with git."""
+ s = Spec('git-url-top-level').concretized()
- pkg = spack.repo.get('git-url-top-level')
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '3.0')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag == 'v3.0'
- assert fetcher.commit is None
- assert fetcher.branch is None
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '3.1')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag == 'v3.1'
- assert fetcher.commit == 'abc31'
- assert fetcher.branch is None
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '3.2')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag is None
- assert fetcher.commit is None
- assert fetcher.branch == 'releases/v3.2'
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '3.3')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag is None
- assert fetcher.commit == 'abc33'
- assert fetcher.branch == 'releases/v3.3'
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '3.4')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag is None
- assert fetcher.commit == 'abc34'
- assert fetcher.branch is None
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, 'submodules')
+ fetcher = spack.fetch_strategy.for_package_version(s.package, version_str)
assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag is None
- assert fetcher.commit is None
- assert fetcher.branch is None
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, 'develop')
- assert isinstance(fetcher, spack.fetch_strategy.GitFetchStrategy)
- assert fetcher.url == 'https://example.com/some/git/repo'
- assert fetcher.tag is None
- assert fetcher.commit is None
- assert fetcher.branch == 'develop'
+ assert fetcher.tag == tag
+ assert fetcher.commit == commit
+ assert fetcher.branch == branch
-def test_git_url_top_level_conflicts(mock_packages, config):
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('version_str', ['1.0', '1.1', '1.2', '1.3'])
+def test_git_url_top_level_conflicts(version_str):
"""Test git fetch strategy inference when url is specified with git."""
-
- pkg = spack.repo.get('git-url-top-level')
-
+ s = Spec('git-url-top-level').concretized()
with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.0')
-
- with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.1')
-
- with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.2')
-
- with pytest.raises(spack.fetch_strategy.FetcherConflict):
- spack.fetch_strategy.for_package_version(pkg, '1.3')
+ spack.fetch_strategy.for_package_version(s.package, version_str)
def test_rpath_args(mutable_database):
@@ -354,25 +277,20 @@ def test_bundle_patch_directive(mock_directive_bundle,
patch(mock_directive_bundle)
-def test_fetch_options(mock_packages, config):
+@pytest.mark.usefixtures('mock_packages', 'config')
+@pytest.mark.parametrize('version_str,digest_end,extra_options', [
+ ('1.0', '10', {'timeout': 42, 'cookie': 'foobar'}),
+ ('1.1', '11', {'timeout': 65}),
+ ('1.2', '12', {'cookie': 'baz'}),
+])
+def test_fetch_options(version_str, digest_end, extra_options):
"""Test fetch options inference."""
-
- pkg = spack.repo.get('fetch-options')
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.0')
- assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.digest == '00000000000000000000000000000010'
- assert fetcher.extra_options == {'timeout': 42, 'cookie': 'foobar'}
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.1')
- assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.digest == '00000000000000000000000000000011'
- assert fetcher.extra_options == {'timeout': 65}
-
- fetcher = spack.fetch_strategy.for_package_version(pkg, '1.2')
+ s = Spec('fetch-options').concretized()
+ leading_zeros = '000000000000000000000000000000'
+ fetcher = spack.fetch_strategy.for_package_version(s.package, version_str)
assert isinstance(fetcher, spack.fetch_strategy.URLFetchStrategy)
- assert fetcher.digest == '00000000000000000000000000000012'
- assert fetcher.extra_options == {'cookie': 'baz'}
+ assert fetcher.digest == leading_zeros + digest_end
+ assert fetcher.extra_options == extra_options
def test_has_test_method_fails(capsys):
diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py
index 63a3cf9a3e..6e977a6b36 100644
--- a/lib/spack/spack/test/packaging.py
+++ b/lib/spack/spack/test/packaging.py
@@ -54,9 +54,8 @@ def fake_fetchify(url, pkg):
@pytest.mark.usefixtures('install_mockery', 'mock_gnupghome')
def test_buildcache(mock_archive, tmpdir):
# tweak patchelf to only do a download
- pspec = Spec("patchelf")
- pspec.concretize()
- pkg = spack.repo.get(pspec)
+ pspec = Spec("patchelf").concretized()
+ pkg = pspec.package
fake_fetchify(pkg.fetcher, pkg)
mkdirp(os.path.join(pkg.prefix, "bin"))
patchelfscr = os.path.join(pkg.prefix, "bin", "patchelf")
diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py
index 0d88b93c23..596811eb99 100644
--- a/lib/spack/spack/test/patch.py
+++ b/lib/spack/spack/test/patch.py
@@ -63,12 +63,13 @@ data_path = os.path.join(spack.paths.test_path, 'data', 'patch')
platform_url_sha,
None)
])
-def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256):
+def test_url_patch(mock_patch_stage, filename, sha256, archive_sha256, config):
# Make a patch object
url = 'file://' + filename
- pkg = spack.repo.get('patch')
+ s = Spec('patch').concretized()
patch = spack.patch.UrlPatch(
- pkg, url, sha256=sha256, archive_sha256=archive_sha256)
+ s.package, url, sha256=sha256, archive_sha256=archive_sha256
+ )
# make a stage
with Stage(url) as stage: # TODO: url isn't used; maybe refactor Stage
diff --git a/lib/spack/spack/test/repo.py b/lib/spack/spack/test/repo.py
index 5dfa9597fc..5b3ebceb10 100644
--- a/lib/spack/spack/test/repo.py
+++ b/lib/spack/spack/test/repo.py
@@ -27,14 +27,14 @@ repo:
def test_repo_getpkg(mutable_mock_repo):
- mutable_mock_repo.get('a')
- mutable_mock_repo.get('builtin.mock.a')
+ mutable_mock_repo.get_pkg_class('a')
+ mutable_mock_repo.get_pkg_class('builtin.mock.a')
def test_repo_multi_getpkg(mutable_mock_repo, extra_repo):
mutable_mock_repo.put_first(extra_repo)
- mutable_mock_repo.get('a')
- mutable_mock_repo.get('builtin.mock.a')
+ mutable_mock_repo.get_pkg_class('a')
+ mutable_mock_repo.get_pkg_class('builtin.mock.a')
def test_repo_multi_getpkgclass(mutable_mock_repo, extra_repo):
@@ -45,17 +45,12 @@ def test_repo_multi_getpkgclass(mutable_mock_repo, extra_repo):
def test_repo_pkg_with_unknown_namespace(mutable_mock_repo):
with pytest.raises(spack.repo.UnknownNamespaceError):
- mutable_mock_repo.get('unknown.a')
+ mutable_mock_repo.get_pkg_class('unknown.a')
def test_repo_unknown_pkg(mutable_mock_repo):
with pytest.raises(spack.repo.UnknownPackageError):
- mutable_mock_repo.get('builtin.mock.nonexistentpackage')
-
-
-def test_repo_anonymous_pkg(mutable_mock_repo):
- with pytest.raises(spack.repo.UnknownPackageError):
- mutable_mock_repo.get('+variant')
+ mutable_mock_repo.get_pkg_class('builtin.mock.nonexistentpackage')
@pytest.mark.maybeslow
@@ -64,7 +59,7 @@ def test_repo_anonymous_pkg(mutable_mock_repo):
)
def test_repo_last_mtime():
latest_mtime = max(os.path.getmtime(p.module.__file__)
- for p in spack.repo.path.all_packages())
+ for p in spack.repo.path.all_package_classes())
assert spack.repo.path.last_mtime() == latest_mtime
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index 566d9ccb8d..b7c0f95332 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -42,13 +42,13 @@ def set_dependency(saved_deps, monkeypatch):
"""
spec = Spec(spec)
# Save original dependencies before making any changes.
- pkg = spack.repo.get(pkg_name)
+ pkg_cls = spack.repo.path.get_pkg_class(pkg_name)
if pkg_name not in saved_deps:
- saved_deps[pkg_name] = (pkg, pkg.dependencies.copy())
+ saved_deps[pkg_name] = (pkg_cls, pkg_cls.dependencies.copy())
- cond = Spec(pkg.name)
- dependency = Dependency(pkg, spec, type=deptypes)
- monkeypatch.setitem(pkg.dependencies, spec.name, {cond: dependency})
+ cond = Spec(pkg_cls.name)
+ dependency = Dependency(pkg_cls, spec, type=deptypes)
+ monkeypatch.setitem(pkg_cls.dependencies, spec.name, {cond: dependency})
return _mock
diff --git a/lib/spack/spack/test/svn_fetch.py b/lib/spack/spack/test/svn_fetch.py
index 5051df5fc8..1e6bbb6ed0 100644
--- a/lib/spack/spack/test/svn_fetch.py
+++ b/lib/spack/spack/test/svn_fetch.py
@@ -49,21 +49,19 @@ def test_fetch(
h = mock_svn_repository.hash
# Construct the package under test
- spec = Spec('svn-test')
- spec.concretize()
- pkg = spack.repo.get(spec)
- monkeypatch.setitem(pkg.versions, ver('svn'), t.args)
+ s = Spec('svn-test').concretized()
+ monkeypatch.setitem(s.package.versions, ver('svn'), t.args)
# Enter the stage directory and check some properties
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:verify_ssl', secure):
- pkg.do_stage()
+ s.package.do_stage()
- with working_dir(pkg.stage.source_path):
+ with working_dir(s.package.stage.source_path):
assert h() == t.revision
- file_path = os.path.join(pkg.stage.source_path, t.file)
- assert os.path.isdir(pkg.stage.source_path)
+ file_path = os.path.join(s.package.stage.source_path, t.file)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
os.unlink(file_path)
@@ -72,10 +70,10 @@ def test_fetch(
untracked_file = 'foobarbaz'
touch(untracked_file)
assert os.path.isfile(untracked_file)
- pkg.do_restage()
+ s.package.do_restage()
assert not os.path.isfile(untracked_file)
- assert os.path.isdir(pkg.stage.source_path)
+ assert os.path.isdir(s.package.stage.source_path)
assert os.path.isfile(file_path)
assert h() == t.revision
diff --git a/lib/spack/spack/test/url_fetch.py b/lib/spack/spack/test/url_fetch.py
index 54cb7e5a3b..9d66afb814 100644
--- a/lib/spack/spack/test/url_fetch.py
+++ b/lib/spack/spack/test/url_fetch.py
@@ -156,20 +156,16 @@ def test_fetch(
checksum = algo.hexdigest()
# Get a spec and tweak the test package with new chcecksum params
- spec = Spec('url-test')
- spec.concretize()
-
- pkg = spack.repo.get('url-test')
- pkg.url = mock_archive.url
- pkg.versions[ver('test')] = {checksum_type: checksum, 'url': pkg.url}
- pkg.spec = spec
+ s = Spec('url-test').concretized()
+ s.package.url = mock_archive.url
+ s.package.versions[ver('test')] = {checksum_type: checksum, 'url': s.package.url}
# Enter the stage directory and check some properties
- with pkg.stage:
+ with s.package.stage:
with spack.config.override('config:verify_ssl', secure):
with spack.config.override('config:url_fetch_method', _fetch_method):
- pkg.do_stage()
- with working_dir(pkg.stage.source_path):
+ s.package.do_stage()
+ with working_dir(s.package.stage.source_path):
assert os.path.exists('configure')
assert is_exe('configure')
@@ -206,15 +202,14 @@ def test_from_list_url(mock_packages, config, spec, url, digest, _fetch_method):
have checksums in the package.
"""
with spack.config.override('config:url_fetch_method', _fetch_method):
- specification = Spec(spec).concretized()
- pkg = spack.repo.get(specification)
- fetch_strategy = fs.from_list_url(pkg)
+ s = Spec(spec).concretized()
+ fetch_strategy = fs.from_list_url(s.package)
assert isinstance(fetch_strategy, fs.URLFetchStrategy)
assert os.path.basename(fetch_strategy.url) == url
assert fetch_strategy.digest == digest
assert fetch_strategy.extra_options == {}
- pkg.fetch_options = {'timeout': 60}
- fetch_strategy = fs.from_list_url(pkg)
+ s.package.fetch_options = {'timeout': 60}
+ fetch_strategy = fs.from_list_url(s.package)
assert fetch_strategy.extra_options == {'timeout': 60}
@@ -243,26 +238,22 @@ def test_new_version_from_list_url(
"""Test non-specific URLs from the url-list-test package."""
with spack.config.override("config:url_fetch_method", _fetch_method):
- pkg = spack.repo.get("url-list-test")
-
- spec = Spec("url-list-test @%s" % requested_version).concretized()
- pkg = spack.repo.get(spec)
- fetch_strategy = fs.from_list_url(pkg)
+ s = Spec("url-list-test @%s" % requested_version).concretized()
+ fetch_strategy = fs.from_list_url(s.package)
assert isinstance(fetch_strategy, fs.URLFetchStrategy)
assert os.path.basename(fetch_strategy.url) == tarball
assert fetch_strategy.digest == digest
assert fetch_strategy.extra_options == {}
- pkg.fetch_options = {"timeout": 60}
- fetch_strategy = fs.from_list_url(pkg)
+ s.package.fetch_options = {"timeout": 60}
+ fetch_strategy = fs.from_list_url(s.package)
assert fetch_strategy.extra_options == {"timeout": 60}
def test_nosource_from_list_url(mock_packages, config):
"""This test confirms BundlePackages do not have list url."""
- pkg = spack.repo.get('nosource')
-
- fetch_strategy = fs.from_list_url(pkg)
+ s = Spec('nosource').concretized()
+ fetch_strategy = fs.from_list_url(s.package)
assert fetch_strategy is None
diff --git a/lib/spack/spack/test/util/package_hash.py b/lib/spack/spack/test/util/package_hash.py
index 3133cd08a7..2d4f00d5dc 100644
--- a/lib/spack/spack/test/util/package_hash.py
+++ b/lib/spack/spack/test/util/package_hash.py
@@ -10,6 +10,7 @@ import pytest
import spack.directives
import spack.paths
+import spack.repo
import spack.util.package_hash as ph
from spack.spec import Spec
from spack.util.unparse import unparse
@@ -19,9 +20,13 @@ datadir = os.path.join(spack.paths.test_path, "data", "unparse")
def compare_sans_name(eq, spec1, spec2):
content1 = ph.canonical_source(spec1)
- content1 = content1.replace(spec1.package.__class__.__name__, 'TestPackage')
+ content1 = content1.replace(
+ spack.repo.path.get_pkg_class(spec1.name).__name__, 'TestPackage'
+ )
content2 = ph.canonical_source(spec2)
- content2 = content2.replace(spec2.package.__class__.__name__, 'TestPackage')
+ content2 = content2.replace(
+ spack.repo.path.get_pkg_class(spec2.name).__name__, 'TestPackage'
+ )
if eq:
assert content1 == content2
else:
@@ -30,12 +35,14 @@ def compare_sans_name(eq, spec1, spec2):
def compare_hash_sans_name(eq, spec1, spec2):
content1 = ph.canonical_source(spec1)
- content1 = content1.replace(spec1.package.__class__.__name__, 'TestPackage')
- hash1 = spec1.package.content_hash(content=content1)
+ pkg_cls1 = spack.repo.path.get_pkg_class(spec1.name)
+ content1 = content1.replace(pkg_cls1.__name__, 'TestPackage')
+ hash1 = pkg_cls1(spec1).content_hash(content=content1)
content2 = ph.canonical_source(spec2)
- content2 = content2.replace(spec2.package.__class__.__name__, 'TestPackage')
- hash2 = spec2.package.content_hash(content=content2)
+ pkg_cls2 = spack.repo.path.get_pkg_class(spec2.name)
+ content2 = content2.replace(pkg_cls2.__name__, 'TestPackage')
+ hash2 = pkg_cls2(spec2).content_hash(content=content2)
if eq:
assert hash1 == hash2
diff --git a/lib/spack/spack/util/mock_package.py b/lib/spack/spack/util/mock_package.py
index 29f9cb472c..312e3f8f10 100644
--- a/lib/spack/spack/util/mock_package.py
+++ b/lib/spack/spack/util/mock_package.py
@@ -33,6 +33,9 @@ class MockPackageBase(object):
"""
self.spec = None
+ def __call__(self, *args, **kwargs):
+ return self
+
def provides(self, vname):
return vname in self.provided
diff --git a/lib/spack/spack/variant.py b/lib/spack/spack/variant.py
index aad453bb11..f350bc2666 100644
--- a/lib/spack/spack/variant.py
+++ b/lib/spack/spack/variant.py
@@ -89,14 +89,14 @@ class Variant(object):
self.group_validator = validator
self.sticky = sticky
- def validate_or_raise(self, vspec, pkg=None):
+ def validate_or_raise(self, vspec, pkg_cls=None):
"""Validate a variant spec against this package variant. Raises an
exception if any error is found.
Args:
vspec (Variant): instance to be validated
- pkg (spack.package_base.Package): the package that required the validation,
- if available
+ pkg_cls (spack.package_base.Package): the package class
+ that required the validation, if available
Raises:
InconsistentValidationError: if ``vspec.name != self.name``
@@ -118,7 +118,7 @@ class Variant(object):
# If the value is exclusive there must be at most one
if not self.multi and len(value) != 1:
- raise MultipleValuesInExclusiveVariantError(vspec, pkg)
+ raise MultipleValuesInExclusiveVariantError(vspec, pkg_cls)
# Check and record the values that are not allowed
not_allowed_values = [
@@ -126,11 +126,11 @@ class Variant(object):
if x != '*' and self.single_value_validator(x) is False
]
if not_allowed_values:
- raise InvalidVariantValueError(self, not_allowed_values, pkg)
+ raise InvalidVariantValueError(self, not_allowed_values, pkg_cls)
# Validate the group of values if needed
if self.group_validator is not None and value != ('*',):
- self.group_validator(pkg.name, self.name, value)
+ self.group_validator(pkg_cls.name, self.name, value)
@property
def allowed_values(self):
diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py
index 4267d307b1..4d59394480 100644
--- a/lib/spack/spack/version.py
+++ b/lib/spack/spack/version.py
@@ -1136,7 +1136,7 @@ class CommitLookup(object):
@property
def pkg(self):
if not self._pkg:
- self._pkg = spack.repo.get(self.pkg_name)
+ self._pkg = spack.repo.path.get_pkg_class(self.pkg_name)
return self._pkg
@property
diff --git a/var/spack/repos/builtin.mock/packages/multimethod/package.py b/var/spack/repos/builtin.mock/packages/multimethod/package.py
index 4f7cd6eca9..16af9198a0 100644
--- a/var/spack/repos/builtin.mock/packages/multimethod/package.py
+++ b/var/spack/repos/builtin.mock/packages/multimethod/package.py
@@ -19,6 +19,16 @@ class Multimethod(MultimethodBase):
homepage = 'http://www.example.com/'
url = 'http://www.example.com/example-1.0.tar.gz'
+ version('5.0', '0123456789abcdef0123456789abcdef')
+ version('4.0', '0123456789abcdef0123456789abcdef')
+ version('3.0', '0123456789abcdef0123456789abcdef')
+ version('2.0', '0123456789abcdef0123456789abcdef')
+ version('1.0', '0123456789abcdef0123456789abcdef')
+
+ variant('mpi', default=False, description='')
+
+ depends_on('mpi', when='+mpi')
+
#
# These functions are only valid for versions 1, 3, and 4.
#
@@ -76,9 +86,9 @@ class Multimethod(MultimethodBase):
def has_a_default(self):
return 'gcc'
- @when('%intel')
+ @when('%clang')
def has_a_default(self):
- return 'intel'
+ return 'clang'
#
# Make sure we can switch methods on different target
diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py
index fe621a5bde..392f3b5910 100644
--- a/var/spack/repos/builtin/packages/gcc/package.py
+++ b/var/spack/repos/builtin/packages/gcc/package.py
@@ -11,6 +11,7 @@ import sys
from archspec.cpu import UnsupportedMicroarchitecture
import llnl.util.tty as tty
+from llnl.util.lang import classproperty
import spack.platforms
import spack.util.executable
@@ -351,8 +352,8 @@ class Gcc(AutotoolsPackage, GNUMirrorPackage):
build_directory = 'spack-build'
- @property
- def executables(self):
+ @classproperty
+ def executables(cls):
names = [r'gcc', r'[^\w]?g\+\+', r'gfortran']
suffixes = [r'', r'-mp-\d+\.\d', r'-\d+\.\d', r'-\d+', r'\d\d']
return [r''.join(x) for x in itertools.product(names, suffixes)]
diff --git a/var/spack/repos/builtin/packages/simmetrix-simmodsuite/package.py b/var/spack/repos/builtin/packages/simmetrix-simmodsuite/package.py
index 22a1d06b15..fd500846bc 100644
--- a/var/spack/repos/builtin/packages/simmetrix-simmodsuite/package.py
+++ b/var/spack/repos/builtin/packages/simmetrix-simmodsuite/package.py
@@ -7,159 +7,160 @@ import os
from spack.package import *
-
-def simmodsuite_releases():
- releases = [
- {
- 'version': '16.0-220312',
- 'components': {
- 'msparalleladapt': ['cc6d6ecba8183f3444e55977af879b297977ff94dd7f6197028110f7e24ea60b', 'paralleladapt'],
- 'msadapt': ['ec4a985f9b29914411d299fecfb1a994224070480be5de5f701d9968ba9da9e5', 'base'],
- 'opencascade': ['008e7232ee3531b70143129e5a664f7db0e232bad9d11d693d725d39986a8aa4', 'opencascade'],
- 'gmvoxel': ['4a74c54c31e9eb93f9a0c09ef3ac88f365efb19666240374aa6d1142db993a2c', 'voxel'],
- 'msadv': ['d33b591147152383130cc2190f1bd7726cb9ea3590468691db3be5815802d888', 'adv'],
- 'pskrnl': ['e154c22c01ecab2e041cf5d87fcb23eab074449dae7f677f17e7863b6da70fdc', 'parasolid'],
- 'gmcore': ['d9ed89d07d83f2c23eca6a27fd9000fd4c8eeefa70ac860aa28a40000a6ec93e', 'base'],
- 'psint': ['5c236e429f28a36a36cb09ec3f4778dc7b6e72447014b684792eea733bb21fd5', 'parasolid'],
- 'msparallelmesh': ['a791f4464da54faafdc63dbcaf3d326ffc49c9ea8d53e36cc57c15607cf72db9', 'parallelmesh'],
- 'mscore': ['48e367e476a03a9fa5389830a6c60824b5d620d04d87392e423a33a331ba3595', 'base'],
- 'fdcore': ['022de14021434d90daee8ea1200c024d98a7eb01bb9cb5a06a3b2f7ffee9c0a1', 'base'],
- 'gmadv': ['6232ec08ef5cff4269d066b035490f33c199fb545355836ef1536b1a00179b2c', 'advmodel'],
- 'gmabstract': ['08a6c7423ed59361c5330dbe00b8914d1d55160de73002e7e552c45c8316f37a', 'abstract'],
- 'discrete': ['f5ae00688cf202e75686955185d95952e7b581b414dd52bfef0d917e5959ab22', 'discrete'],
- 'aciskrnl': ['c2c7b0c495d47a5662765f1b0c6f52863032e63384d85241e6313c4b773e9ed2', 'acis'],
- },
- 'docs': {
- 'GeomSimParasolid': ['3420fcc1ac67cff8f46b79553cfe478f34676b9b0cd1fa913255b48cbdfd6ad4', 'parasolid'],
- 'GeomSimAcis': ['77b31bfb368f1e7981b3a81087e4e287c560e0a0cd08920b36dc81fea25bcdfa', 'acis'],
- 'MeshSimAdvanced': ['abeeb0cb10cf3074295a880412e0568b653f2784b1de19f0f8ede5eec536a8bd', 'adv'],
- 'GeomSim': ['b1e762111eb8025b966b0aca4bef3768325d9f1c1e3c72a1246b59539e444eb2', 'base'],
- 'GeomSimVoxel': ['bc43f931670657a2cae79f9a2a02048b511fa6e405f15e583631e9f6888e7000', 'voxel'],
- 'ParallelMeshSimAdapt': ['dd3a0fd6b889dadb45f9a894f684353fffa25bf15be60ae8e09d0c035045e192', 'paralleladapt'],
- 'GeomSimAdvanced': ['3e971ae069baf94b38794318f97f16dc25cf50f6a81413903fbe17407cbd73b3', 'advmodel'],
- 'GeomSimGranite': ['e438c19bb94a182068bf327988bd1ff9c1e391876cd9b7c74760b98cbfd08763', 'granite'],
- 'FieldSim': ['5ede572cbb7539921482390e5890daa92399a5f1ee68a98d3241a7d062667d9d', 'base'],
- 'MeshSimAdapt': ['c4be287da651c68e246034b28e141143d83fc3986fd680174a0d6de7b1cc35ab', 'base'],
- 'GeomSimOpenCascade': ['34a8d628d07ab66159d6151276e93fdabfcc92a370f5927b66a71d3a8545652c', 'opencascade'],
- 'GeomSimDiscrete': ['d2b11367334401ec57390a658715e91bbf3e3a0e8521fab1ad5d3f7c215b2921', 'discrete'],
- 'GeomSimAbstract': ['601b0179b65a385a39d241a9a4e3074e4f834c817e836bea07516015c769e666', 'abstract'],
- 'GeomSimDiscreteModeling': ['619b8254d8e3bcc94e84551e997b577dd9325131d084c3b3693ab665b7e4213b', 'discrete'],
- 'ParallelMeshSim': ['5b74b9b5f9290111366e341c12d4777635e375523d42cb0a2b24aa1bfa8ab8c4', 'parallelmesh'],
- 'MeshSim': ['2f1944e1853a550cc474201790555212e4b7a21d3675715de416718a789ccae2', 'base'],
- }
+RELEASES = [
+ {
+ 'version': '16.0-220312',
+ 'components': {
+ 'msparalleladapt': ['cc6d6ecba8183f3444e55977af879b297977ff94dd7f6197028110f7e24ea60b', 'paralleladapt'],
+ 'msadapt': ['ec4a985f9b29914411d299fecfb1a994224070480be5de5f701d9968ba9da9e5', 'base'],
+ 'opencascade': ['008e7232ee3531b70143129e5a664f7db0e232bad9d11d693d725d39986a8aa4', 'opencascade'],
+ 'gmvoxel': ['4a74c54c31e9eb93f9a0c09ef3ac88f365efb19666240374aa6d1142db993a2c', 'voxel'],
+ 'msadv': ['d33b591147152383130cc2190f1bd7726cb9ea3590468691db3be5815802d888', 'adv'],
+ 'pskrnl': ['e154c22c01ecab2e041cf5d87fcb23eab074449dae7f677f17e7863b6da70fdc', 'parasolid'],
+ 'gmcore': ['d9ed89d07d83f2c23eca6a27fd9000fd4c8eeefa70ac860aa28a40000a6ec93e', 'base'],
+ 'psint': ['5c236e429f28a36a36cb09ec3f4778dc7b6e72447014b684792eea733bb21fd5', 'parasolid'],
+ 'msparallelmesh': ['a791f4464da54faafdc63dbcaf3d326ffc49c9ea8d53e36cc57c15607cf72db9', 'parallelmesh'],
+ 'mscore': ['48e367e476a03a9fa5389830a6c60824b5d620d04d87392e423a33a331ba3595', 'base'],
+ 'fdcore': ['022de14021434d90daee8ea1200c024d98a7eb01bb9cb5a06a3b2f7ffee9c0a1', 'base'],
+ 'gmadv': ['6232ec08ef5cff4269d066b035490f33c199fb545355836ef1536b1a00179b2c', 'advmodel'],
+ 'gmabstract': ['08a6c7423ed59361c5330dbe00b8914d1d55160de73002e7e552c45c8316f37a', 'abstract'],
+ 'discrete': ['f5ae00688cf202e75686955185d95952e7b581b414dd52bfef0d917e5959ab22', 'discrete'],
+ 'aciskrnl': ['c2c7b0c495d47a5662765f1b0c6f52863032e63384d85241e6313c4b773e9ed2', 'acis'],
},
- {
- 'version': '16.0-210623',
- 'components': {
- 'gmadv': ['c40dac44695db6e97c4d4c06d1eb6eac93518c93d7860c77a69f3ea30fea3b90', 'advmodel'],
- 'msparallelmesh': ['57d710b74887731ea0e664a154489747033af433852809181c11e8065752eaf4', 'parallelmesh'],
- 'gmcore': ['5bd04f175fdf5a088140af5ca3fa03934251c097044b47fdf3ea2cd0afc28547', 'base'],
- 'pskrnl': ['87957818b20839d3835a343894c396f7c591d1f0bfd728d33ad21b1adb4e887c', 'parasolid'],
- 'msadapt': ['5ba66819bb2c56eb1e07e6c2659afc8c971005b08ed059f8c62a185236e45dac', 'base'],
- 'gmvoxel': ['15dfc389665086ea37b9835fecd6b46070572878308796afa960077cc2bf7e0a', 'voxel'],
- 'msparalleladapt': ['1db2c34a398c5965a2a675006c96a3603e0124188b52159776b7c616efa48457', 'paralleladapt'],
- 'mscore': ['7029871c52d6c3bb782ae2acb7360130105649cd9cf63815ae95cf4089cb786d', 'base'],
- 'psint': ['c8a3dbacafa70b13bc9fb8322699a1cfc812b2cfd3ea05cba9135623eae761d8', 'parasolid'],
- 'fdcore': ['75f9bcd7cb9ab9dedb73166539c08b53bd8e91c5619d3dce605ba19c63d1ee5c', 'base'],
- 'msadv': ['0018e0a6b9d7724867f7379bc619269481c318ee4dfd0724511c032534ae04a1', 'adv'],
- 'aciskrnl': ['2a9b9da9b0c09857de7fef0dea0e96222bd30e297bd37bea962751dab6762500', 'acis'],
- 'discrete': ['f17cd198f8749c763cc8e200cfd6734604e1d316a48d7d0e537a9a890d884904', 'discrete'],
- 'gmabstract': ['068d0309d5ff9668fc0474edf7f4e20503827400e34492e2ed55b46a0c9e1858', 'abstract'],
- },
- 'docs': {
- 'GeomSimAdvanced': ['02e4566042ae4de10c4acb577142e82d15f32caa296fe1b578c62a38da707066', 'advmodel'],
- 'MeshSim': ['cc1dc77cece7aac6ded003c872c651ad8321bc9ce931ad141b17d2de7bf513c5', 'base'],
- 'GeomSimVoxel': ['49b8f85f59acc8c973bf46c1f999a0ae64cdf129371587879de056c0ac3500d8', 'voxel'],
- 'MeshSimAdvanced': ['2d2689979104414d91d804ca3c34a69104e572b8f231c4e324b09e57675b61cc', 'adv'],
- 'GeomSimGranite': ['17f18831a12b06c0e085486d94d3a4275d7ed94ad53fec689e8877217856c750', 'granite'],
- 'GeomSimParasolid': ['492bd311cc42dadd1f76064c57d35e886b9a7da4c48576ec4d34844fcdaddb8d', 'parasolid'],
- 'GeomSimAcis': ['341c6aeda7f9189f4e886cb75c5989cb9ece6ecba1b1c9d5273b94f74a3dd40b', 'acis'],
- 'GeomSimDiscrete': ['e9d42da613a3acadbcdee5d8d6fc3b093f58b51d158f2a392b7da0e5f74e0388', 'discrete'],
- 'MeshSimAdapt': ['e27510e588105bdb0ca62c2629dfd41dfca6039b7b2ff0298ef83d3a48d7dd23', 'base'],
- 'GeomSimAbstract': ['398c1a15efcddd3b86a7b0334af6f8b529710f815f73f5655d3c7271e92b194e', 'abstract'],
- 'GeomSimDiscreteModeling': ['f444aed59569731f65eea920322adcc224c67b715ecba85a1898cf418de58237', 'discrete'],
- 'FieldSim': ['bac947998d4de1c4edba271645310d4784290bec30bf0cf41d00ae6ea8b27c97', 'base'],
- 'GeomSim': ['95cb24165d47701daa8da7131ca1173d38f4dab80c1ca0d75843b464fed92097', 'base'],
- 'ParallelMeshSim': ['fb1e3ac0ab7208d771057880c693e529e7c821772265b89125d371a1b34fa651', 'parallelmesh'],
- 'ParallelMeshSimAdapt': ['246c5c8b30194239f41a79f2ffd205fd9ae69bcb8127d19a94f12c278a27f106', 'paralleladapt'],
- }
+ 'docs': {
+ 'GeomSimParasolid': ['3420fcc1ac67cff8f46b79553cfe478f34676b9b0cd1fa913255b48cbdfd6ad4', 'parasolid'],
+ 'GeomSimAcis': ['77b31bfb368f1e7981b3a81087e4e287c560e0a0cd08920b36dc81fea25bcdfa', 'acis'],
+ 'MeshSimAdvanced': ['abeeb0cb10cf3074295a880412e0568b653f2784b1de19f0f8ede5eec536a8bd', 'adv'],
+ 'GeomSim': ['b1e762111eb8025b966b0aca4bef3768325d9f1c1e3c72a1246b59539e444eb2', 'base'],
+ 'GeomSimVoxel': ['bc43f931670657a2cae79f9a2a02048b511fa6e405f15e583631e9f6888e7000', 'voxel'],
+ 'ParallelMeshSimAdapt': ['dd3a0fd6b889dadb45f9a894f684353fffa25bf15be60ae8e09d0c035045e192',
+ 'paralleladapt'],
+ 'GeomSimAdvanced': ['3e971ae069baf94b38794318f97f16dc25cf50f6a81413903fbe17407cbd73b3', 'advmodel'],
+ 'GeomSimGranite': ['e438c19bb94a182068bf327988bd1ff9c1e391876cd9b7c74760b98cbfd08763', 'granite'],
+ 'FieldSim': ['5ede572cbb7539921482390e5890daa92399a5f1ee68a98d3241a7d062667d9d', 'base'],
+ 'MeshSimAdapt': ['c4be287da651c68e246034b28e141143d83fc3986fd680174a0d6de7b1cc35ab', 'base'],
+ 'GeomSimOpenCascade': ['34a8d628d07ab66159d6151276e93fdabfcc92a370f5927b66a71d3a8545652c', 'opencascade'],
+ 'GeomSimDiscrete': ['d2b11367334401ec57390a658715e91bbf3e3a0e8521fab1ad5d3f7c215b2921', 'discrete'],
+ 'GeomSimAbstract': ['601b0179b65a385a39d241a9a4e3074e4f834c817e836bea07516015c769e666', 'abstract'],
+ 'GeomSimDiscreteModeling': ['619b8254d8e3bcc94e84551e997b577dd9325131d084c3b3693ab665b7e4213b', 'discrete'],
+ 'ParallelMeshSim': ['5b74b9b5f9290111366e341c12d4777635e375523d42cb0a2b24aa1bfa8ab8c4', 'parallelmesh'],
+ 'MeshSim': ['2f1944e1853a550cc474201790555212e4b7a21d3675715de416718a789ccae2', 'base'],
+ }
+ },
+ {
+ 'version': '16.0-210623',
+ 'components': {
+ 'gmadv': ['c40dac44695db6e97c4d4c06d1eb6eac93518c93d7860c77a69f3ea30fea3b90', 'advmodel'],
+ 'msparallelmesh': ['57d710b74887731ea0e664a154489747033af433852809181c11e8065752eaf4', 'parallelmesh'],
+ 'gmcore': ['5bd04f175fdf5a088140af5ca3fa03934251c097044b47fdf3ea2cd0afc28547', 'base'],
+ 'pskrnl': ['87957818b20839d3835a343894c396f7c591d1f0bfd728d33ad21b1adb4e887c', 'parasolid'],
+ 'msadapt': ['5ba66819bb2c56eb1e07e6c2659afc8c971005b08ed059f8c62a185236e45dac', 'base'],
+ 'gmvoxel': ['15dfc389665086ea37b9835fecd6b46070572878308796afa960077cc2bf7e0a', 'voxel'],
+ 'msparalleladapt': ['1db2c34a398c5965a2a675006c96a3603e0124188b52159776b7c616efa48457', 'paralleladapt'],
+ 'mscore': ['7029871c52d6c3bb782ae2acb7360130105649cd9cf63815ae95cf4089cb786d', 'base'],
+ 'psint': ['c8a3dbacafa70b13bc9fb8322699a1cfc812b2cfd3ea05cba9135623eae761d8', 'parasolid'],
+ 'fdcore': ['75f9bcd7cb9ab9dedb73166539c08b53bd8e91c5619d3dce605ba19c63d1ee5c', 'base'],
+ 'msadv': ['0018e0a6b9d7724867f7379bc619269481c318ee4dfd0724511c032534ae04a1', 'adv'],
+ 'aciskrnl': ['2a9b9da9b0c09857de7fef0dea0e96222bd30e297bd37bea962751dab6762500', 'acis'],
+ 'discrete': ['f17cd198f8749c763cc8e200cfd6734604e1d316a48d7d0e537a9a890d884904', 'discrete'],
+ 'gmabstract': ['068d0309d5ff9668fc0474edf7f4e20503827400e34492e2ed55b46a0c9e1858', 'abstract'],
},
- {
- 'version': '14.0-191122',
- 'components': {
- 'gmadv': ['01cea5f7aff5e442ea544df054969740ad33e2ff4097cf02de31874d16a0c7c2', 'advmodel'],
- 'msadapt': ['69839698f24969f97963869fd212bdcff0b5d52dd40ec3fdc710d878e43b527a', 'base'],
- 'gmvoxel': ['bfea15e1fc5d258ed9db69132042a848ca81995e92bf265215e4b88d08a308a8', 'voxel'],
- 'gmabstract': ['dccdcd4b71758e4110cd69b0befa7875e5c1f3871f87478410c6676da3f39092', 'abstract'],
- 'fdcore': ['6981b2eb0c0143e6abc3ec29918fc3552f81018755770bf922d2491275984e1a', 'base'],
- 'msparallelmesh': ['1e1a431ec9dd85354ff42c6a2a41df7fbe3dfe5d296f40105c4d3aa372639dc3', 'parallelmesh'],
- 'mscore': ['bca80fcb2c86e7b6dc0259681ccd73197ce85c47f00f1910bd6b518fa0b3a092', 'base'],
- 'discrete': ['430e5f2270864b1ab9c8dff75d2510147a0c5cde8af0828975d9e38661be3a35', 'discrete'],
- 'gmimport': ['e83b3c43b7c695fa96ed42253a4b317a2882bcb8987fd3225c09492e353e49aa', 'import'],
- 'pskrnl': ['31455cfce746b2339b3644f3890d4444014fb839654a9f576ec747d28ff6c1c4', 'parasolid'],
- 'gmcore': ['af5d89b9ce266cac5b45f2bf96e1324e87e54c6e2f568bd5b6a85c41122d39e4', 'base'],
- 'aciskrnl': ['764e5633e6d502951788accfb8c34ed59430a4779a44d1775fd67f9aab8a654a', 'acis'],
- 'msparalleladapt': ['8ae607112958f6b9d319736c71a6597cf99a8a59ceed733f2a939cb9cfa6dd67', 'paralleladapt'],
- 'psint': ['f6c90b2fe87e690b2cba20f357d03c5962fed91541d6b79e01dc25cb8f01d1e0', 'parasolid'],
- 'msadv': ['f18a8285d539cb07b00fde06fe970d958eceabf2a10182bcca6c8ad1c074c395', 'adv'],
- },
- 'docs': {
- 'MeshSim': ['f3c475072f270ff49ac2f6639ca1cddb0642889648cbea7df1a3f1b85f7cac36', 'base'],
- 'GeomSimVoxel': ['9f4ee5a8204fee1d899cb912e0379f8be7a826e81ca0a0d8a670a4b804ca1276', 'voxel'],
- 'MeshSimAdvanced': ['8c8bc3709238e600e8938c7c345588f8947d89eae98a228b0d0e3d46f5f4c0d9', 'adv'],
- 'GeomSimDiscreteModeling': ['4e8e26a88e8a5ad396a637597a52f5973d8f77abc0a5b99fa737caf37226d6cc', 'discrete'],
- 'GeomSimAdvanced': ['5efb38317d6be7862ce34024922ca372b30691a30af820474e2e26e4c3055278', 'advmodel'],
- 'GeomSimParasolid': ['6851bdaf6d96e7b2335fce3394825e9876800f0aba0a42644758dc1bd06f60fe', 'parasolid'],
- 'GeomSimImport': ['d931ecfc332460c825b473c0950c7ae8ff9f845e0d1565f85bfd7698da5e6d26', 'import'],
- 'ParallelMeshSim': ['0f0d235b25a660271e401488e412220f574b341dadb827f7b82f0e93172b5cdb', 'parallelmesh'],
- 'ParallelMeshSimAdapt': ['7964ebbd7e8d971ea85fc5260e44f7e876da5ad474dc67d8d6fc939bfa5ba454', 'paralleladapt'],
- 'GeomSimAcis': ['dea82efbc4e3043ecda163be792ef295057e08be17654a7783ce7ca5e786f950', 'acis'],
- 'MeshSimAdapt': ['ee4d5595572c1fe1a0d78bd9b85c774a55e994c48170450d6c5f34b05fcf2411', 'base'],
- 'FieldSim': ['6b09b4ab278911d3e9229fd4cd8dc92ba188f151d42d9d7b96d542aad2af1fac', 'base'],
- 'GeomSim': ['0673823d649998367c0e427055911eae971bb6e8c76625882e7a7901f4d18c44', 'base'],
- 'GeomSimDiscrete': ['58dfd33fc5cdd2ab24e9084377943f28d5ba68b8c017b11b71cde64c5e4f2113', 'discrete'],
- 'GeomSimAbstract': ['16248cd2a0d133029eb4b79d61397da008e4d5b5c3eaf0161a0a44148b0bc519', 'abstract'],
- }
+ 'docs': {
+ 'GeomSimAdvanced': ['02e4566042ae4de10c4acb577142e82d15f32caa296fe1b578c62a38da707066', 'advmodel'],
+ 'MeshSim': ['cc1dc77cece7aac6ded003c872c651ad8321bc9ce931ad141b17d2de7bf513c5', 'base'],
+ 'GeomSimVoxel': ['49b8f85f59acc8c973bf46c1f999a0ae64cdf129371587879de056c0ac3500d8', 'voxel'],
+ 'MeshSimAdvanced': ['2d2689979104414d91d804ca3c34a69104e572b8f231c4e324b09e57675b61cc', 'adv'],
+ 'GeomSimGranite': ['17f18831a12b06c0e085486d94d3a4275d7ed94ad53fec689e8877217856c750', 'granite'],
+ 'GeomSimParasolid': ['492bd311cc42dadd1f76064c57d35e886b9a7da4c48576ec4d34844fcdaddb8d', 'parasolid'],
+ 'GeomSimAcis': ['341c6aeda7f9189f4e886cb75c5989cb9ece6ecba1b1c9d5273b94f74a3dd40b', 'acis'],
+ 'GeomSimDiscrete': ['e9d42da613a3acadbcdee5d8d6fc3b093f58b51d158f2a392b7da0e5f74e0388', 'discrete'],
+ 'MeshSimAdapt': ['e27510e588105bdb0ca62c2629dfd41dfca6039b7b2ff0298ef83d3a48d7dd23', 'base'],
+ 'GeomSimAbstract': ['398c1a15efcddd3b86a7b0334af6f8b529710f815f73f5655d3c7271e92b194e', 'abstract'],
+ 'GeomSimDiscreteModeling': ['f444aed59569731f65eea920322adcc224c67b715ecba85a1898cf418de58237', 'discrete'],
+ 'FieldSim': ['bac947998d4de1c4edba271645310d4784290bec30bf0cf41d00ae6ea8b27c97', 'base'],
+ 'GeomSim': ['95cb24165d47701daa8da7131ca1173d38f4dab80c1ca0d75843b464fed92097', 'base'],
+ 'ParallelMeshSim': ['fb1e3ac0ab7208d771057880c693e529e7c821772265b89125d371a1b34fa651', 'parallelmesh'],
+ 'ParallelMeshSimAdapt': ['246c5c8b30194239f41a79f2ffd205fd9ae69bcb8127d19a94f12c278a27f106',
+ 'paralleladapt'],
+ }
+ },
+ {
+ 'version': '14.0-191122',
+ 'components': {
+ 'gmadv': ['01cea5f7aff5e442ea544df054969740ad33e2ff4097cf02de31874d16a0c7c2', 'advmodel'],
+ 'msadapt': ['69839698f24969f97963869fd212bdcff0b5d52dd40ec3fdc710d878e43b527a', 'base'],
+ 'gmvoxel': ['bfea15e1fc5d258ed9db69132042a848ca81995e92bf265215e4b88d08a308a8', 'voxel'],
+ 'gmabstract': ['dccdcd4b71758e4110cd69b0befa7875e5c1f3871f87478410c6676da3f39092', 'abstract'],
+ 'fdcore': ['6981b2eb0c0143e6abc3ec29918fc3552f81018755770bf922d2491275984e1a', 'base'],
+ 'msparallelmesh': ['1e1a431ec9dd85354ff42c6a2a41df7fbe3dfe5d296f40105c4d3aa372639dc3', 'parallelmesh'],
+ 'mscore': ['bca80fcb2c86e7b6dc0259681ccd73197ce85c47f00f1910bd6b518fa0b3a092', 'base'],
+ 'discrete': ['430e5f2270864b1ab9c8dff75d2510147a0c5cde8af0828975d9e38661be3a35', 'discrete'],
+ 'gmimport': ['e83b3c43b7c695fa96ed42253a4b317a2882bcb8987fd3225c09492e353e49aa', 'import'],
+ 'pskrnl': ['31455cfce746b2339b3644f3890d4444014fb839654a9f576ec747d28ff6c1c4', 'parasolid'],
+ 'gmcore': ['af5d89b9ce266cac5b45f2bf96e1324e87e54c6e2f568bd5b6a85c41122d39e4', 'base'],
+ 'aciskrnl': ['764e5633e6d502951788accfb8c34ed59430a4779a44d1775fd67f9aab8a654a', 'acis'],
+ 'msparalleladapt': ['8ae607112958f6b9d319736c71a6597cf99a8a59ceed733f2a939cb9cfa6dd67', 'paralleladapt'],
+ 'psint': ['f6c90b2fe87e690b2cba20f357d03c5962fed91541d6b79e01dc25cb8f01d1e0', 'parasolid'],
+ 'msadv': ['f18a8285d539cb07b00fde06fe970d958eceabf2a10182bcca6c8ad1c074c395', 'adv'],
+ },
+ 'docs': {
+ 'MeshSim': ['f3c475072f270ff49ac2f6639ca1cddb0642889648cbea7df1a3f1b85f7cac36', 'base'],
+ 'GeomSimVoxel': ['9f4ee5a8204fee1d899cb912e0379f8be7a826e81ca0a0d8a670a4b804ca1276', 'voxel'],
+ 'MeshSimAdvanced': ['8c8bc3709238e600e8938c7c345588f8947d89eae98a228b0d0e3d46f5f4c0d9', 'adv'],
+ 'GeomSimDiscreteModeling': ['4e8e26a88e8a5ad396a637597a52f5973d8f77abc0a5b99fa737caf37226d6cc', 'discrete'],
+ 'GeomSimAdvanced': ['5efb38317d6be7862ce34024922ca372b30691a30af820474e2e26e4c3055278', 'advmodel'],
+ 'GeomSimParasolid': ['6851bdaf6d96e7b2335fce3394825e9876800f0aba0a42644758dc1bd06f60fe', 'parasolid'],
+ 'GeomSimImport': ['d931ecfc332460c825b473c0950c7ae8ff9f845e0d1565f85bfd7698da5e6d26', 'import'],
+ 'ParallelMeshSim': ['0f0d235b25a660271e401488e412220f574b341dadb827f7b82f0e93172b5cdb', 'parallelmesh'],
+ 'ParallelMeshSimAdapt': ['7964ebbd7e8d971ea85fc5260e44f7e876da5ad474dc67d8d6fc939bfa5ba454',
+ 'paralleladapt'],
+ 'GeomSimAcis': ['dea82efbc4e3043ecda163be792ef295057e08be17654a7783ce7ca5e786f950', 'acis'],
+ 'MeshSimAdapt': ['ee4d5595572c1fe1a0d78bd9b85c774a55e994c48170450d6c5f34b05fcf2411', 'base'],
+ 'FieldSim': ['6b09b4ab278911d3e9229fd4cd8dc92ba188f151d42d9d7b96d542aad2af1fac', 'base'],
+ 'GeomSim': ['0673823d649998367c0e427055911eae971bb6e8c76625882e7a7901f4d18c44', 'base'],
+ 'GeomSimDiscrete': ['58dfd33fc5cdd2ab24e9084377943f28d5ba68b8c017b11b71cde64c5e4f2113', 'discrete'],
+ 'GeomSimAbstract': ['16248cd2a0d133029eb4b79d61397da008e4d5b5c3eaf0161a0a44148b0bc519', 'abstract'],
+ }
+ },
+ {
+ 'version': '12.0-191027',
+ 'components': {
+ 'gmadv': ['1a133523062974c4d9acb1d52baa3893dc891482aebaaeb79a7dc907461d5dbc', 'advmodel'],
+ 'fdcore': ['c3a89093f811cb489698d203dbe68ca910e6c67ea75c0a7aba73dd369508b9ec', 'base'],
+ 'mscore': ['a2f043278d45d8729020b663c66c57960fcec33dafd3d90db55f0a9e32723bce', 'base'],
+ 'msparallelmesh': ['2f6fd47d3c5c2f1ece4634985a522ac599d3cee20ad8a4623f252cc75aa32c4c', 'parallelmesh'],
+ 'msparalleladapt': ['8d288730b1300215a32f3b21624bd2e0e2d8a684fe928459757fcec7e0aeb7d3', 'paralleladapt'],
+ 'gmabstract': ['3b608f21e6c11db5bb48e49f9cd7e9d88aeec4feadebd778529a5c9d506d08c6', 'abstract'],
+ 'gmimport': ['fc1626c7b1522b90eaa3926e1253b84d28440c7df8634decdedb79b5229be800', 'import'],
+ 'discrete': ['a15ead08138f0c59c7ee46cd0d348d4f26e1b021d2580a134cf2b84a7337bcf9', 'discrete'],
+ 'aciskrnl': ['8773f00e08d237052c877e79d1a869214f59891e812d70df938b2a5e5423a96f', 'acis'],
+ 'msadv': ['41bdb9555ab9feb0891f0832a49fc29777d40957473f315e1c33e1c0077cba7d', 'adv'],
+ 'psint': ['b040ab48833eb2a748f757e2de6929f3002aa98db459ba92bd9a88e443e5cb07', 'parasolid'],
+ 'gmvoxel': ['19fba83c9c7eac20d9613236530fbae652dc8edef35233214f0f92b81c91a877', 'voxel'],
+ 'msadapt': ['1a752adb6724c3328fffb26f1aebed007d3c2a5df725cd29aa0cf0fdfda1f39a', 'base'],
+ 'gmcore': ['ec95bae84b36644e6e04cf0a6b4e813a51990d0a30519176ebb8a05f681af7f2', 'base'],
+ 'pskrnl': ['7b7b4952513e06c8c23aa8f7c1748f5c199d9af70ea06c4a359412237ed8ac1d', 'parasolid'],
},
- {
- 'version': '12.0-191027',
- 'components': {
- 'gmadv': ['1a133523062974c4d9acb1d52baa3893dc891482aebaaeb79a7dc907461d5dbc', 'advmodel'],
- 'fdcore': ['c3a89093f811cb489698d203dbe68ca910e6c67ea75c0a7aba73dd369508b9ec', 'base'],
- 'mscore': ['a2f043278d45d8729020b663c66c57960fcec33dafd3d90db55f0a9e32723bce', 'base'],
- 'msparallelmesh': ['2f6fd47d3c5c2f1ece4634985a522ac599d3cee20ad8a4623f252cc75aa32c4c', 'parallelmesh'],
- 'msparalleladapt': ['8d288730b1300215a32f3b21624bd2e0e2d8a684fe928459757fcec7e0aeb7d3', 'paralleladapt'],
- 'gmabstract': ['3b608f21e6c11db5bb48e49f9cd7e9d88aeec4feadebd778529a5c9d506d08c6', 'abstract'],
- 'gmimport': ['fc1626c7b1522b90eaa3926e1253b84d28440c7df8634decdedb79b5229be800', 'import'],
- 'discrete': ['a15ead08138f0c59c7ee46cd0d348d4f26e1b021d2580a134cf2b84a7337bcf9', 'discrete'],
- 'aciskrnl': ['8773f00e08d237052c877e79d1a869214f59891e812d70df938b2a5e5423a96f', 'acis'],
- 'msadv': ['41bdb9555ab9feb0891f0832a49fc29777d40957473f315e1c33e1c0077cba7d', 'adv'],
- 'psint': ['b040ab48833eb2a748f757e2de6929f3002aa98db459ba92bd9a88e443e5cb07', 'parasolid'],
- 'gmvoxel': ['19fba83c9c7eac20d9613236530fbae652dc8edef35233214f0f92b81c91a877', 'voxel'],
- 'msadapt': ['1a752adb6724c3328fffb26f1aebed007d3c2a5df725cd29aa0cf0fdfda1f39a', 'base'],
- 'gmcore': ['ec95bae84b36644e6e04cf0a6b4e813a51990d0a30519176ebb8a05f681af7f2', 'base'],
- 'pskrnl': ['7b7b4952513e06c8c23aa8f7c1748f5c199d9af70ea06c4a359412237ed8ac1d', 'parasolid'],
- },
- 'docs': {
- 'FieldSim': ['5109d91fe61ccdaf0af5aa869aea9c38ec98760746ec3983d100f870cbb1cb63', 'base'],
- 'ParallelMeshSim': ['a1e6618a77022a9580beac4c698dd4b9aa70f617a27db9ce13ab1f2388475290', 'parallelmesh'],
- 'GeomSimAcis': ['f0319b32eb417fa9b237575d9b2dc1c061848888c36fd4da97d97cdbb3cf19c3', 'acis'],
- 'GeomSimAbstract': ['c44023e6944522057c47925db49089031c7de9b67938ca6a987e04fadfeda9b7', 'abstract'],
- 'GeomSimDiscrete': ['ad648752fa7d2dc1ce234a612e28ce84eb1f064a1decadf17b42e9fe56967350', 'discrete'],
- 'MeshSimAdapt': ['dcb7d6ec74c910b41b5ae707d9fd4664fcb3a0fdb2c876caaa28a6f1cf701024', 'base'],
- 'MeshSim': ['e5a8cb300b1e13b9f2733bf8b738872ffb37d9df15836a6ab264483c10000696', 'base'],
- 'GeomSimParasolid': ['2bf33cc5b3879716437d45fde0a02caaa165e37d248d05b4b00708e76573a15e', 'parasolid'],
- 'GeomSimImport': ['5309433dcdce660e062412f070719eefcc6299764e9b0169533ff343c9c9c406', 'import'],
- 'ParallelMeshSimAdapt': ['2e8e0ceede3107b85dba9536f3bbf5e6959793073a5147548cfb01ca568c8da2', 'paralleladapt'],
- 'GeomSimDiscreteModeling': ['ff88ec234b890315cc36539e3f73f4f977dab94160860950e7b7ee0303c9b55e', 'discrete'],
- 'GeomSim': ['62ae33372f999d5e62a1b7b161ddd7de04c055adc85cfd258e088c95b76d5fef', 'base'],
- 'GeomSimVoxel': ['7a624ddaebd833077511acac3efd4b4c1dab09bd9feff40aba0813182eeb262f', 'voxel'],
- 'GeomSimAdvanced': ['f0ab801ddf3d701a4ac3f8c47900cc858a4488eb0fe2f663504ba260cd270d20', 'advmodel'],
- 'MeshSimAdvanced': ['bb532027e4fcc311a7c376383da010aed5ee133a9122b186a4e5c7d0cf1d976b', 'adv'],
- }
+ 'docs': {
+ 'FieldSim': ['5109d91fe61ccdaf0af5aa869aea9c38ec98760746ec3983d100f870cbb1cb63', 'base'],
+ 'ParallelMeshSim': ['a1e6618a77022a9580beac4c698dd4b9aa70f617a27db9ce13ab1f2388475290', 'parallelmesh'],
+ 'GeomSimAcis': ['f0319b32eb417fa9b237575d9b2dc1c061848888c36fd4da97d97cdbb3cf19c3', 'acis'],
+ 'GeomSimAbstract': ['c44023e6944522057c47925db49089031c7de9b67938ca6a987e04fadfeda9b7', 'abstract'],
+ 'GeomSimDiscrete': ['ad648752fa7d2dc1ce234a612e28ce84eb1f064a1decadf17b42e9fe56967350', 'discrete'],
+ 'MeshSimAdapt': ['dcb7d6ec74c910b41b5ae707d9fd4664fcb3a0fdb2c876caaa28a6f1cf701024', 'base'],
+ 'MeshSim': ['e5a8cb300b1e13b9f2733bf8b738872ffb37d9df15836a6ab264483c10000696', 'base'],
+ 'GeomSimParasolid': ['2bf33cc5b3879716437d45fde0a02caaa165e37d248d05b4b00708e76573a15e', 'parasolid'],
+ 'GeomSimImport': ['5309433dcdce660e062412f070719eefcc6299764e9b0169533ff343c9c9c406', 'import'],
+ 'ParallelMeshSimAdapt': ['2e8e0ceede3107b85dba9536f3bbf5e6959793073a5147548cfb01ca568c8da2',
+ 'paralleladapt'],
+ 'GeomSimDiscreteModeling': ['ff88ec234b890315cc36539e3f73f4f977dab94160860950e7b7ee0303c9b55e', 'discrete'],
+ 'GeomSim': ['62ae33372f999d5e62a1b7b161ddd7de04c055adc85cfd258e088c95b76d5fef', 'base'],
+ 'GeomSimVoxel': ['7a624ddaebd833077511acac3efd4b4c1dab09bd9feff40aba0813182eeb262f', 'voxel'],
+ 'GeomSimAdvanced': ['f0ab801ddf3d701a4ac3f8c47900cc858a4488eb0fe2f663504ba260cd270d20', 'advmodel'],
+ 'MeshSimAdvanced': ['bb532027e4fcc311a7c376383da010aed5ee133a9122b186a4e5c7d0cf1d976b', 'adv'],
}
- ]
- return releases
+ }
+]
def simmetrix_makecomponenturl(name):
@@ -237,8 +238,7 @@ class SimmetrixSimmodsuite(Package):
oslib = 'x64_rhel7_gcc48'
- releases = simmodsuite_releases()
- for release in releases:
+ for release in RELEASES:
# define the version using the mscore tarball
sim_version = release['version']
main_pkg_name = 'mscore'
@@ -246,22 +246,22 @@ class SimmetrixSimmodsuite(Package):
sha256 = release['components'][main_pkg_name][0]
version(sim_version, sha256=sha256, url=url)
# define resources for the other tarballs
- for name, atts in release['components'].items():
+ for _name, atts in release['components'].items():
# skip the tarball used for the version(...) call
- if name == 'mscore':
+ if _name == 'mscore':
continue
sha256 = atts[0]
feature = atts[1]
- url = simmetrix_makecomponenturl(name)
+ url = simmetrix_makecomponenturl(_name)
condition = "@{0}+{1}".format(sim_version, feature)
- simmetrix_resource(name, url, sha256, condition)
+ simmetrix_resource(_name, url, sha256, condition)
# define resources for the document zip files
- for name, atts in release['docs'].items():
+ for _name, atts in release['docs'].items():
sha256 = atts[0]
feature = atts[1]
- url = simmetrix_makedocurl(name)
+ url = simmetrix_makedocurl(_name)
condition = "@{0}+{1}".format(sim_version, feature)
- simmetrix_resource(name, url, sha256, condition)
+ simmetrix_resource(_name, url, sha256, condition)
def setup_dependent_build_environment(self, env, dependent_spec):
archlib = join_path(prefix.lib, self.oslib)
@@ -277,7 +277,7 @@ class SimmetrixSimmodsuite(Package):
if not spec.satisfies('platform=linux'):
raise InstallError('Only the linux platform is supported')
source_path = self.stage.source_path
- for release in simmodsuite_releases():
+ for release in RELEASES:
simversion = release['version']
if simversion != spec.version.string:
continue