From 7bd735416dcf8235efa77bf21f7e92beacf7d433 Mon Sep 17 00:00:00 2001
From: alalazo <massimiliano.culpo@googlemail.com>
Date: Sun, 23 Oct 2016 22:38:19 +0200
Subject: package.py : moved each specialized package to its own module file

---
 lib/spack/spack/__init__.py                        |   4 +-
 lib/spack/spack/build_systems/__init__.py          |   0
 lib/spack/spack/build_systems/autotools.py         | 106 ++++++++++++++
 lib/spack/spack/build_systems/cmake.py             | 143 +++++++++++++++++++
 lib/spack/spack/build_systems/editable_makefile.py |  77 ++++++++++
 lib/spack/spack/package.py                         | 155 ---------------------
 var/spack/repos/builtin/packages/astyle/package.py |   4 +-
 7 files changed, 331 insertions(+), 158 deletions(-)
 create mode 100644 lib/spack/spack/build_systems/__init__.py
 create mode 100644 lib/spack/spack/build_systems/autotools.py
 create mode 100644 lib/spack/spack/build_systems/cmake.py
 create mode 100644 lib/spack/spack/build_systems/editable_makefile.py

diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index c7d592befb..918e17323b 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -196,7 +196,9 @@ __all__ = ['Package',
            'alldeps',
            'nolink']
 from spack.package import Package, ExtensionConflictError
-from spack.package import CMakePackage, AutotoolsPackage, EditableMakefile
+from spack.build_systems.editable_makefile import EditableMakefile
+from spack.build_systems.autotools import AutotoolsPackage
+from spack.build_systems.cmake import CMakePackage
 from spack.version import Version, ver
 from spack.spec import DependencySpec, alldeps, nolink
 from spack.multimethod import when
diff --git a/lib/spack/spack/build_systems/__init__.py b/lib/spack/spack/build_systems/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py
new file mode 100644
index 0000000000..0bb5576708
--- /dev/null
+++ b/lib/spack/spack/build_systems/autotools.py
@@ -0,0 +1,106 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+import os.path
+
+import llnl.util.tty as tty
+from spack.package import PackageBase
+
+
+class AutotoolsPackage(PackageBase):
+    """Specialized class for packages that are built using GNU Autotools
+
+    This class provides four phases that can be overridden:
+    - autoreconf
+    - configure
+    - build
+    - install
+
+    They all have sensible defaults and for many packages the only thing
+    necessary will be to override `configure_args`
+    """
+    phases = ['autoreconf', 'configure', 'build', 'install']
+    # To be used in UI queries that require to know which
+    # build-system class we are using
+    build_system_class = 'AutotoolsPackage'
+
+    def autoreconf(self, spec, prefix):
+        """Not needed usually, configure should be already there"""
+        pass
+
+    @PackageBase.sanity_check('autoreconf')
+    def is_configure_or_die(self):
+        """Checks the presence of a `configure` file after the
+        autoreconf phase"""
+        if not os.path.exists('configure'):
+            raise RuntimeError(
+                'configure script not found in {0}'.format(os.getcwd()))
+
+    def configure_args(self):
+        """Method to be overridden. Should return an iterable containing
+        all the arguments that must be passed to configure, except --prefix
+        """
+        return []
+
+    def configure(self, spec, prefix):
+        """Runs configure with the arguments specified in `configure_args`
+        and an appropriately set prefix
+        """
+        options = ['--prefix={0}'.format(prefix)] + self.configure_args()
+        inspect.getmodule(self).configure(*options)
+
+    def build(self, spec, prefix):
+        """The usual `make` after configure"""
+        inspect.getmodule(self).make()
+
+    def install(self, spec, prefix):
+        """...and the final `make install` after configure"""
+        inspect.getmodule(self).make('install')
+
+    @PackageBase.sanity_check('build')
+    @PackageBase.on_package_attributes(run_tests=True)
+    def _run_default_function(self):
+        """This function is run after build if self.run_tests == True
+
+        It will search for a method named `check` and run it. A sensible
+        default is provided in the base class.
+        """
+        try:
+            fn = getattr(self, 'check')
+            tty.msg('Trying default sanity checks [check]')
+            fn()
+        except AttributeError:
+            tty.msg('Skipping default sanity checks [method `check` not implemented]')  # NOQA: ignore=E501
+
+    def check(self):
+        """Default test : search the Makefile for targets `test` and `check`
+        and run them if found.
+        """
+        self._if_make_target_execute('test')
+        self._if_make_target_execute('check')
+
+    # Check that self.prefix is there after installation
+    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
new file mode 100644
index 0000000000..cb1076d7b7
--- /dev/null
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -0,0 +1,143 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+import os
+import platform
+
+import llnl.util.tty as tty
+import spack.build_environment
+from llnl.util.filesystem import working_dir, join_path
+from spack.package import PackageBase
+
+
+class CMakePackage(PackageBase):
+    """Specialized class for packages that are built using cmake
+
+    This class provides three phases that can be overridden:
+    - cmake
+    - build
+    - install
+
+    They all have sensible defaults and for many packages the only thing
+    necessary will be to override `cmake_args`
+    """
+    phases = ['cmake', 'build', 'install']
+    # To be used in UI queries that require to know which
+    # build-system class we are using
+    build_system_class = 'CMakePackage'
+
+    def build_type(self):
+        """Override to provide the correct build_type in case a complex
+        logic is needed
+        """
+        return 'RelWithDebInfo'
+
+    def root_cmakelists_dir(self):
+        """Directory where to find the root CMakeLists.txt"""
+        return self.stage.source_path
+
+    @property
+    def std_cmake_args(self):
+        """Standard cmake arguments provided as a property for
+        convenience of package writers
+        """
+        # standard CMake arguments
+        return CMakePackage._std_args(self)
+
+    @staticmethod
+    def _std_args(pkg):
+        """Computes the standard cmake arguments for a generic package"""
+        try:
+            build_type = pkg.build_type()
+        except AttributeError:
+            build_type = 'RelWithDebInfo'
+
+        args = ['-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix),
+                '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type),
+                '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON']
+        if platform.mac_ver()[0]:
+            args.append('-DCMAKE_FIND_FRAMEWORK:STRING=LAST')
+
+        # Set up CMake rpath
+        args.append('-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE')
+        rpaths = ':'.join(spack.build_environment.get_rpaths(pkg))
+        args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths))
+        return args
+
+    def build_directory(self):
+        """Override to provide another place to build the package"""
+        return join_path(self.stage.source_path, 'spack-build')
+
+    def cmake_args(self):
+        """Method to be overridden. Should return an iterable containing
+        all the arguments that must be passed to configure, except:
+        - CMAKE_INSTALL_PREFIX
+        - CMAKE_BUILD_TYPE
+        """
+        return []
+
+    def cmake(self, spec, prefix):
+        """Run cmake in the build directory"""
+        options = [self.root_cmakelists_dir()] + self.std_cmake_args + \
+            self.cmake_args()
+        create = not os.path.exists(self.build_directory())
+        with working_dir(self.build_directory(), create=create):
+            inspect.getmodule(self).cmake(*options)
+
+    def build(self, spec, prefix):
+        """The usual `make` after cmake"""
+        with working_dir(self.build_directory()):
+            inspect.getmodule(self).make()
+
+    def install(self, spec, prefix):
+        """...and the final `make install` after cmake"""
+        with working_dir(self.build_directory()):
+            inspect.getmodule(self).make('install')
+
+    @PackageBase.sanity_check('build')
+    @PackageBase.on_package_attributes(run_tests=True)
+    def _run_default_function(self):
+        """This function is run after build if self.run_tests == True
+
+        It will search for a method named `check` and run it. A sensible
+        default is provided in the base class.
+        """
+        try:
+            fn = getattr(self, 'check')
+            tty.msg('Trying default build sanity checks [check]')
+            fn()
+        except AttributeError:
+            tty.msg('Skipping default build sanity checks [method `check` not implemented]')  # NOQA: ignore=E501
+
+    def check(self):
+        """Default test : search the Makefile for the target `test`
+        and run them if found.
+        """
+        with working_dir(self.build_directory()):
+            self._if_make_target_execute('test')
+
+    # Check that self.prefix is there after installation
+    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/build_systems/editable_makefile.py b/lib/spack/spack/build_systems/editable_makefile.py
new file mode 100644
index 0000000000..e3adea8363
--- /dev/null
+++ b/lib/spack/spack/build_systems/editable_makefile.py
@@ -0,0 +1,77 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+
+import inspect
+
+from llnl.util.filesystem import working_dir
+from spack.package import PackageBase
+
+
+class EditableMakefile(PackageBase):
+    """Specialized class for packages that are built using editable Makefiles
+
+    This class provides three phases that can be overridden:
+    - edit
+    - build
+    - install
+
+    It is necessary to override the 'edit' phase, while 'build' and 'install'
+    have sensible defaults.
+    """
+    phases = ['edit', 'build', 'install']
+    # To be used in UI queries that require to know which
+    # build-system class we are using
+    build_system_class = 'EditableMakefile'
+
+    def build_directory(self):
+        """Directory where the main Makefile is located"""
+        return self.stage.source_path
+
+    def build_args(self):
+        """List of arguments that should be passed to make at build time"""
+        return []
+
+    def install_args(self):
+        """List of arguments that should be passed to make at install time"""
+        return []
+
+    def edit(self, spec, prefix):
+        """This phase cannot be defaulted for obvious reasons..."""
+        raise NotImplementedError('\'edit\' function not implemented')
+
+    def build(self, spec, prefix):
+        """Default build phase : call make passing build_args"""
+        args = self.build_args()
+        with working_dir(self.build_directory()):
+            inspect.getmodule(self).make(*args)
+
+    def install(self, spec, prefix):
+        """Default install phase : call make passing install_args"""
+        args = self.install_args() + ['install']
+        with working_dir(self.build_directory()):
+            inspect.getmodule(self).make(*args)
+
+    # Check that self.prefix is there after installation
+    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 9483f370dd..52dbd40f6f 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -38,7 +38,6 @@ import copy
 import functools
 import inspect
 import os
-import platform
 import re
 import sys
 import textwrap
@@ -48,7 +47,6 @@ from StringIO import StringIO
 import llnl.util.lock
 import llnl.util.tty as tty
 import spack
-import spack.build_environment
 import spack.compilers
 import spack.directives
 import spack.error
@@ -1698,159 +1696,6 @@ class Package(PackageBase):
     PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
 
 
-class EditableMakefile(PackageBase):
-    phases = ['edit', 'build', 'install']
-    # To be used in UI queries that require to know which
-    # build-system class we are using
-    build_system_class = 'EditableMakefile'
-
-    def wdir(self):
-        return self.stage.source_path
-
-    def build_args(self):
-        return []
-
-    def install_args(self):
-        return []
-
-    def edit(self, spec, prefix):
-        raise NotImplementedError('\'edit\' function not implemented')
-
-    def build(self, spec, prefix):
-        args = self.build_args()
-        with working_dir(self.wdir()):
-            inspect.getmodule(self).make(*args)
-
-    def install(self, spec, prefix):
-        args = self.install_args() + ['install']
-        with working_dir(self.wdir()):
-            inspect.getmodule(self).make(*args)
-
-    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
-class AutotoolsPackage(PackageBase):
-    phases = ['autoreconf', 'configure', 'build', 'install']
-    # To be used in UI queries that require to know which
-    # build-system class we are using
-    build_system_class = 'AutotoolsPackage'
-
-    def autoreconf(self, spec, prefix):
-        """Not needed usually, configure should be already there"""
-        pass
-
-    @PackageBase.sanity_check('autoreconf')
-    def is_configure_or_die(self):
-        if not os.path.exists('configure'):
-            raise RuntimeError(
-                'configure script not found in {0}'.format(os.getcwd()))
-
-    def configure_args(self):
-        return []
-
-    def configure(self, spec, prefix):
-        options = ['--prefix={0}'.format(prefix)] + self.configure_args()
-        inspect.getmodule(self).configure(*options)
-
-    def build(self, spec, prefix):
-        inspect.getmodule(self).make()
-
-    def install(self, spec, prefix):
-        inspect.getmodule(self).make('install')
-
-    @PackageBase.sanity_check('build')
-    @PackageBase.on_package_attributes(run_tests=True)
-    def _run_default_function(self):
-        try:
-            fn = getattr(self, 'check')
-            tty.msg('Trying default sanity checks [check]')
-            fn()
-        except AttributeError:
-            tty.msg('Skipping default sanity checks [method `check` not implemented]')  # NOQA: ignore=E501
-
-    def check(self):
-        self._if_make_target_execute('test')
-        self._if_make_target_execute('check')
-
-    # This will be used as a registration decorator in user
-    # packages, if need be
-    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
-class CMakePackage(PackageBase):
-    phases = ['cmake', 'build', 'install']
-    # To be used in UI queries that require to know which
-    # build-system class we are using
-    build_system_class = 'CMakePackage'
-
-    def build_type(self):
-        return 'RelWithDebInfo'
-
-    def root_cmakelists_dir(self):
-        return self.stage.source_path
-
-    @property
-    def std_cmake_args(self):
-        # standard CMake arguments
-        return CMakePackage._std_args(self)
-
-    @staticmethod
-    def _std_args(pkg):
-        try:
-            build_type = pkg.build_type()
-        except AttributeError:
-            build_type = 'RelWithDebInfo'
-
-        args = ['-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix),
-                '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type),
-                '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON']
-        if platform.mac_ver()[0]:
-            args.append('-DCMAKE_FIND_FRAMEWORK:STRING=LAST')
-
-        # Set up CMake rpath
-        args.append('-DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=FALSE')
-        rpaths = ':'.join(spack.build_environment.get_rpaths(pkg))
-        args.append('-DCMAKE_INSTALL_RPATH:STRING={0}'.format(rpaths))
-        return args
-
-    def build_directory(self):
-        return join_path(self.stage.source_path, 'spack-build')
-
-    def cmake_args(self):
-        return []
-
-    def cmake(self, spec, prefix):
-        options = [self.root_cmakelists_dir()] + self.std_cmake_args + \
-            self.cmake_args()
-        create = not os.path.exists(self.build_directory())
-        with working_dir(self.build_directory(), create=create):
-            inspect.getmodule(self).cmake(*options)
-
-    def build(self, spec, prefix):
-        with working_dir(self.build_directory()):
-            inspect.getmodule(self).make()
-
-    def install(self, spec, prefix):
-        with working_dir(self.build_directory()):
-            inspect.getmodule(self).make('install')
-
-    @PackageBase.sanity_check('build')
-    @PackageBase.on_package_attributes(run_tests=True)
-    def _run_default_function(self):
-        try:
-            fn = getattr(self, 'check')
-            tty.msg('Trying default build sanity checks [check]')
-            fn()
-        except AttributeError:
-            tty.msg('Skipping default build sanity checks [method `check` not implemented]')  # NOQA: ignore=E501
-
-    def check(self):
-        with working_dir(self.build_directory()):
-            self._if_make_target_execute('test')
-
-    PackageBase.sanity_check('install')(PackageBase.sanity_check_prefix)
-
-
 def install_dependency_symlinks(pkg, spec, prefix):
     """Execute a dummy install and flatten dependencies"""
     flatten_dependencies(spec, prefix)
diff --git a/var/spack/repos/builtin/packages/astyle/package.py b/var/spack/repos/builtin/packages/astyle/package.py
index 7acb77b304..fdd9c2111e 100644
--- a/var/spack/repos/builtin/packages/astyle/package.py
+++ b/var/spack/repos/builtin/packages/astyle/package.py
@@ -37,11 +37,11 @@ class Astyle(EditableMakefile):
 
     parallel = False
 
-    def wdir(self):
+    def build_directory(self):
         return join_path(self.stage.source_path, 'build', self.compiler.name)
 
     def edit(self, spec, prefix):
-        makefile = join_path(self.wdir(), 'Makefile')
+        makefile = join_path(self.build_directory(), 'Makefile')
         filter_file(r'^CXX\s*=.*', 'CXX=%s' % spack_cxx, makefile)
 
     def install_args(self):
-- 
cgit v1.2.3-70-g09d2