diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index c61f8262f7..50f4e715b1 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -96,25 +96,35 @@ def __get__(self, instance, owner): phase = getattr(instance, self.name) @functools.wraps(phase) def phase_wrapper(spec, prefix): + # Check instance attributes at the beginning of a phase + self._on_phase_start(instance) # Execute phase pre-conditions, # and give them the chance to fail for check in self.preconditions: - check(instance) - # Do something sensible at some point + check(instance) # Do something sensible at some point phase(spec, prefix) # Execute phase sanity_checks, # and give them the chance to fail for check in self.sanity_checks: check(instance) - if getattr(instance, 'last_phase', None) == self.name: - raise StopIteration('Stopping at \'{0}\' phase'.format(self.name)) + # Check instance attributes at the end of a phase + self._on_phase_exit(instance) return phase_wrapper + def _on_phase_start(self, instance): + pass + + def _on_phase_exit(self, instance): + # If a phase has a matching last_phase attribute, + # stop the installation process raising a StopIteration + if getattr(instance, 'last_phase', None) == self.name: + raise StopIteration('Stopping at \'{0}\' phase'.format(self.name)) + class PackageMeta(type): """Conveniently transforms attributes to permit extensible phases - Iterates over the attribute 'phase' and creates / updates private + Iterates over the attribute 'phases' and creates / updates private InstallPhase attributes in the class that is being initialized """ phase_fmt = '_InstallPhase_{0}' @@ -156,14 +166,25 @@ def _append_checks(check_name): def _register_checks(cls, check_type, *args): def _register_sanity_checks(func): attr_name = PackageMeta.phase_fmt.format(check_type) - sanity_checks = getattr(meta, attr_name) + check_list = getattr(meta, attr_name) for item in args: - checks = sanity_checks.setdefault(item, []) + checks = check_list.setdefault(item, []) checks.append(func) - setattr(meta, attr_name, sanity_checks) + setattr(meta, attr_name, check_list) return func return _register_sanity_checks + @staticmethod + def on_package_attributes(**attrs): + def _execute_under_condition(func): + @functools.wraps(func) + def _wrapper(instance): + # If all the attributes have the value we require, then execute + if all([getattr(instance, key, None) == value for key, value in attrs.items()]): + func(instance) + return _wrapper + return _execute_under_condition + @classmethod def precondition(cls, *args): return cls._register_checks('preconditions', *args) @@ -181,6 +202,9 @@ def sanity_check(cls, *args): if all([not hasattr(x, 'precondition') for x in bases]): attr_dict['precondition'] = precondition + if all([not hasattr(x, 'on_package_attributes') for x in bases]): + attr_dict['on_package_attributes'] = on_package_attributes + # Preconditions _append_checks('preconditions') # Sanity checks diff --git a/var/spack/repos/builtin/packages/hdf5/package.py b/var/spack/repos/builtin/packages/hdf5/package.py index 54c74901f0..3b2600e671 100644 --- a/var/spack/repos/builtin/packages/hdf5/package.py +++ b/var/spack/repos/builtin/packages/hdf5/package.py @@ -29,8 +29,8 @@ class Hdf5(AutotoolsPackage): """HDF5 is a data model, library, and file format for storing and managing - data. It supports an unlimited variety of datatypes, and is designed for - flexible and efficient I/O and for high volume and complex data. + data. It supports an unlimited variety of datatypes, and is designed for + flexible and efficient I/O and for high volume and complex data. """ homepage = "http://www.hdfgroup.org/HDF5/" @@ -54,9 +54,9 @@ class Hdf5(AutotoolsPackage): variant('szip', default=False, description='Enable szip support') variant('threadsafe', default=False, description='Enable thread-safe capabilities') - depends_on("mpi", when='+mpi') - depends_on("szip", when='+szip') - depends_on("zlib") + depends_on('mpi', when='+mpi') + depends_on('szip', when='+szip') + depends_on('zlib') @AutotoolsPackage.precondition('configure') def validate(self): @@ -140,15 +140,9 @@ def configure_args(self): ]) return ["--with-zlib=%s" % spec['zlib'].prefix] + extra_args - #configure( - # "--prefix=%s" % prefix, - # "--with-zlib=%s" % spec['zlib'].prefix, - # *extra_args) - #make() - #make("install") - #self.check_install(spec) @AutotoolsPackage.sanity_check('install') + @AutotoolsPackage.on_package_attributes(run_tests=True) def check_install(self): "Build and run a small program to test the installed HDF5 library" spec = self.spec diff --git a/var/spack/repos/builtin/packages/lzo/package.py b/var/spack/repos/builtin/packages/lzo/package.py index edf6dc1d4c..9232bbe4e6 100644 --- a/var/spack/repos/builtin/packages/lzo/package.py +++ b/var/spack/repos/builtin/packages/lzo/package.py @@ -44,6 +44,7 @@ def configure_args(self): ] @AutotoolsPackage.sanity_check('build') + @AutotoolsPackage.on_package_attributes(run_tests=True) def check(self): - if self.extra_args.get('build-tests', False): - make('check') + make('check') + make('test')