Add extensions command.
This commit is contained in:
		@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
from llnl.util.filesystem import mkdirp
 | 
			
		||||
from llnl.util.filesystem import *
 | 
			
		||||
 | 
			
		||||
empty_file_name = '.spack-empty'
 | 
			
		||||
 | 
			
		||||
@@ -93,6 +93,7 @@ def traverse_tree(source_root, dest_root, rel_path='', **kwargs):
 | 
			
		||||
    for f in os.listdir(source_path):
 | 
			
		||||
        source_child = os.path.join(source_path, f)
 | 
			
		||||
        dest_child   = os.path.join(dest_path, f)
 | 
			
		||||
        rel_child    = os.path.join(rel_path, f)
 | 
			
		||||
 | 
			
		||||
        # Treat as a directory
 | 
			
		||||
        if os.path.isdir(source_child) and (
 | 
			
		||||
@@ -101,7 +102,7 @@ def traverse_tree(source_root, dest_root, rel_path='', **kwargs):
 | 
			
		||||
            # When follow_nonexisting isn't set, don't descend into dirs
 | 
			
		||||
            # in source that do not exist in dest
 | 
			
		||||
            if follow_nonexisting or os.path.exists(dest_child):
 | 
			
		||||
                tuples = traverse_tree(source_child, dest_child, rel_path, **kwargs)
 | 
			
		||||
                tuples = traverse_tree(source_root, dest_root, rel_child, **kwargs)
 | 
			
		||||
                for t in tuples: yield t
 | 
			
		||||
 | 
			
		||||
        # Treat as a file.
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
from external import argparse
 | 
			
		||||
 | 
			
		||||
import llnl.util.tty as tty
 | 
			
		||||
from llnl.util.tty.colify import colify
 | 
			
		||||
 | 
			
		||||
import spack
 | 
			
		||||
import spack.cmd
 | 
			
		||||
@@ -66,10 +67,10 @@ def extensions(parser, args):
 | 
			
		||||
 | 
			
		||||
    exts = spack.install_layout.get_extensions(spec)
 | 
			
		||||
    if not exts:
 | 
			
		||||
        tty.msg("%s has no activated extensions." % spec.short_spec)
 | 
			
		||||
        tty.msg("%s has no activated extensions." % spec.cshort_spec)
 | 
			
		||||
    else:
 | 
			
		||||
        tty.msg("Showing %d activated extension%s for package:"
 | 
			
		||||
                % (len(exts), 's' if len(exts) > 1 else ''),
 | 
			
		||||
                spec.short_spec)
 | 
			
		||||
        tty.msg("Extensions for package %s:" % spec.cshort_spec)
 | 
			
		||||
        colify(pkg.name for pkg in spack.db.extensions_for(spec))
 | 
			
		||||
        print
 | 
			
		||||
        tty.msg("%d currently activated:" % len(exts))
 | 
			
		||||
        spack.cmd.find.display_specs(exts, mode=args.mode)
 | 
			
		||||
 
 | 
			
		||||
@@ -269,8 +269,8 @@ def extension_file_path(self, spec):
 | 
			
		||||
    def get_extensions(self, spec):
 | 
			
		||||
        _check_concrete(spec)
 | 
			
		||||
 | 
			
		||||
        path = self.extension_file_path(spec)
 | 
			
		||||
        extensions = set()
 | 
			
		||||
        path = self.extension_file_path(spec)
 | 
			
		||||
        if os.path.exists(path):
 | 
			
		||||
            with closing(open(path)) as ext_file:
 | 
			
		||||
                for line in ext_file:
 | 
			
		||||
 
 | 
			
		||||
@@ -522,6 +522,11 @@ def is_extension(self):
 | 
			
		||||
        return len(self.extendees) > 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def extends(self, spec):
 | 
			
		||||
        return (spec.name in self.extendees and
 | 
			
		||||
                spec.satisfies(self.extendees[spec.name][0]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def activated(self):
 | 
			
		||||
        if not self.spec.concrete:
 | 
			
		||||
 
 | 
			
		||||
@@ -112,6 +112,11 @@ def providers_for(self, vpkg_spec):
 | 
			
		||||
        return providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @_autospec
 | 
			
		||||
    def extensions_for(self, extendee_spec):
 | 
			
		||||
        return [p for p in self.all_packages() if p.extends(extendee_spec)]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def dirname_for_package_name(self, pkg_name):
 | 
			
		||||
        """Get the directory name for a particular package.  This is the
 | 
			
		||||
           directory that contains its package.py file."""
 | 
			
		||||
 
 | 
			
		||||
@@ -552,6 +552,13 @@ def short_spec(self):
 | 
			
		||||
        return self.format('$_$@$%@$+$=$#')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def cshort_spec(self):
 | 
			
		||||
        """Returns a version of the spec with the dependencies hashed
 | 
			
		||||
           instead of completely enumerated."""
 | 
			
		||||
        return self.format('$_$@$%@$+$=$#', color=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def prefix(self):
 | 
			
		||||
        return Prefix(spack.install_layout.path_for_spec(self))
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ class PyBasemap(Package):
 | 
			
		||||
    geos_version = {'1.0.7' : '3.3.3'}
 | 
			
		||||
 | 
			
		||||
    extends('python')
 | 
			
		||||
    depends_on('py-setuptools')
 | 
			
		||||
    depends_on('py-numpy')
 | 
			
		||||
    depends_on('py-matplotlib')
 | 
			
		||||
    depends_on('py-pil')
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
from spack import *
 | 
			
		||||
import spack
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
from contextlib import closing
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Python(Package):
 | 
			
		||||
    """The Python programming language."""
 | 
			
		||||
@@ -29,6 +32,10 @@ def install(self, spec, prefix):
 | 
			
		||||
        make("install")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # ========================================================================
 | 
			
		||||
    # Set up environment to make install easy for python extensions.
 | 
			
		||||
    # ========================================================================
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def python_lib_dir(self):
 | 
			
		||||
        return os.path.join('lib', 'python%d.%d' % self.version[:2])
 | 
			
		||||
@@ -60,21 +67,81 @@ def setup_extension_environment(self, module, spec, ext_spec):
 | 
			
		||||
        mkdirp(module.site_packages_dir)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def make_ignore(self, args):
 | 
			
		||||
    # ========================================================================
 | 
			
		||||
    # Handle specifics of activating and deactivating python modules.
 | 
			
		||||
    # ========================================================================
 | 
			
		||||
 | 
			
		||||
    def python_ignore(self, ext_pkg, args):
 | 
			
		||||
        """Add some ignore files to activate/deactivate args."""
 | 
			
		||||
        orig_ignore = args.get('ignore', lambda f: False)
 | 
			
		||||
 | 
			
		||||
        def ignore(filename):
 | 
			
		||||
            return (re.search(r'/site\.pyc?$', filename) or
 | 
			
		||||
                    re.search(r'\.pth$', filename) or
 | 
			
		||||
            # Always ignore easy-install.pth, as it needs to be merged.
 | 
			
		||||
            patterns = [r'easy-install\.pth$']
 | 
			
		||||
 | 
			
		||||
            # Ignore pieces of setuptools installed by other packages.
 | 
			
		||||
            if ext_pkg.name != 'py-setuptools':
 | 
			
		||||
                patterns.append(r'/site\.pyc?$')
 | 
			
		||||
                patterns.append(r'setuptools\.pth')
 | 
			
		||||
                patterns.append(r'bin/easy_install[^/]*$')
 | 
			
		||||
                patterns.append(r'setuptools.*egg$')
 | 
			
		||||
 | 
			
		||||
            return (any(re.search(p, filename) for p in patterns) or
 | 
			
		||||
                    orig_ignore(filename))
 | 
			
		||||
 | 
			
		||||
        return ignore
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def write_easy_install_pth(self, extensions):
 | 
			
		||||
        paths = []
 | 
			
		||||
        for ext in extensions:
 | 
			
		||||
            ext_site_packages = os.path.join(ext.prefix, self.site_packages_dir)
 | 
			
		||||
            easy_pth = "%s/easy-install.pth" % ext_site_packages
 | 
			
		||||
 | 
			
		||||
            if not os.path.isfile(easy_pth):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            with closing(open(easy_pth)) as f:
 | 
			
		||||
                for line in f:
 | 
			
		||||
                    line = line.rstrip()
 | 
			
		||||
 | 
			
		||||
                    # Skip lines matching these criteria
 | 
			
		||||
                    if not line: continue
 | 
			
		||||
                    if re.search(r'^(import|#)', line): continue
 | 
			
		||||
                    if (ext.name != 'py-setuptools' and
 | 
			
		||||
                        re.search(r'setuptools.*egg$', line)): continue
 | 
			
		||||
 | 
			
		||||
                    paths.append(line)
 | 
			
		||||
 | 
			
		||||
        site_packages = os.path.join(self.prefix, self.site_packages_dir)
 | 
			
		||||
        main_pth = "%s/easy-install.pth" % site_packages
 | 
			
		||||
 | 
			
		||||
        if not paths:
 | 
			
		||||
            if os.path.isfile(main_pth):
 | 
			
		||||
                os.remove(main_pth)
 | 
			
		||||
 | 
			
		||||
        else:
 | 
			
		||||
            with closing(open(main_pth, 'w')) as f:
 | 
			
		||||
                f.write("import sys; sys.__plen = len(sys.path)\n")
 | 
			
		||||
                for path in paths:
 | 
			
		||||
                    f.write("%s\n" % path)
 | 
			
		||||
                f.write("import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; "
 | 
			
		||||
                        "p=getattr(sys,'__egginsert',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)\n")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def activate(self, ext_pkg, **args):
 | 
			
		||||
        args.update(ignore=self.make_ignore(args))
 | 
			
		||||
        args.update(ignore=self.python_ignore(ext_pkg, args))
 | 
			
		||||
        super(Python, self).activate(ext_pkg, **args)
 | 
			
		||||
 | 
			
		||||
        extensions = set(spack.install_layout.get_extensions(self.spec))
 | 
			
		||||
        extensions.add(ext_pkg.spec)
 | 
			
		||||
        self.write_easy_install_pth(extensions)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def deactivate(self, ext_pkg, **args):
 | 
			
		||||
        args.update(ignore=self.make_ignore(args))
 | 
			
		||||
        args.update(ignore=self.python_ignore(ext_pkg, args))
 | 
			
		||||
        super(Python, self).deactivate(ext_pkg, **args)
 | 
			
		||||
 | 
			
		||||
        extensions = set(spack.install_layout.get_extensions(self.spec))
 | 
			
		||||
        extensions.remove(ext_pkg.spec)
 | 
			
		||||
        self.write_easy_install_pth(extensions)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user