summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2015-01-20 00:23:16 -0800
committerTodd Gamblin <tgamblin@llnl.gov>2015-02-02 11:19:54 -0800
commitff9cb94f4f92112739f53881bcb0a9a19811684d (patch)
treede65cde58b0af24403178d2d16ff073ce60cfc2b
parent9fa489b7f2dab452929729e300f189f8c50b817c (diff)
downloadspack-ff9cb94f4f92112739f53881bcb0a9a19811684d.tar.gz
spack-ff9cb94f4f92112739f53881bcb0a9a19811684d.tar.bz2
spack-ff9cb94f4f92112739f53881bcb0a9a19811684d.tar.xz
spack-ff9cb94f4f92112739f53881bcb0a9a19811684d.zip
Add arguements to extends() and activate/deactivate.
-rw-r--r--lib/spack/spack/package.py40
-rw-r--r--lib/spack/spack/relations.py17
-rw-r--r--var/spack/packages/python/package.py32
3 files changed, 69 insertions, 20 deletions
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index ae34f8ae45..bd63c2e0c0 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -497,17 +497,27 @@ class Package(object):
@property
def extendee_spec(self):
"""Spec of the extendee of this package, or None if it is not an extension."""
- if not self.extendees: return None
-
+ if not self.extendees:
+ return None
name = next(iter(self.extendees))
if not name in self.spec:
- return self.extendees[name]
+ spec, kwargs = self.extendees[name]
+ return spec
# Need to do this to get the concrete version of the spec
return self.spec[name]
@property
+ def extendee_args(self):
+ """Spec of the extendee of this package, or None if it is not an extension."""
+ if not self.extendees:
+ return None
+ name = next(iter(self.extendees))
+ return self.extendees[name][1]
+
+
+ @property
def is_extension(self):
return len(self.extendees) > 0
@@ -949,6 +959,8 @@ class Package(object):
def _sanity_check_extension(self):
+ if not self.is_extension:
+ raise ValueError("This package is not an extension.")
extendee_package = self.extendee_spec.package
extendee_package._check_extendable()
@@ -967,14 +979,14 @@ class Package(object):
activate() directly.
"""
self._sanity_check_extension()
- self.extendee_spec.package.activate(self)
+ self.extendee_spec.package.activate(self, **self.extendee_args)
spack.install_layout.add_extension(self.extendee_spec, self.spec)
tty.msg("Activated extension %s for %s."
% (self.spec.short_spec, self.extendee_spec.short_spec))
- def activate(self, extension):
+ def activate(self, extension, **kwargs):
"""Symlinks all files from the extension into extendee's install dir.
Package authors can override this method to support other
@@ -983,17 +995,20 @@ class Package(object):
always executed.
"""
+ ignore_files = set(spack.install_layout.hidden_file_paths)
+ ignore_files.update(kwargs.get('ignore', ()))
+
tree = LinkTree(extension.prefix)
- conflict = tree.find_conflict(
- self.prefix, ignore=spack.install_layout.hidden_file_paths)
+ conflict = tree.find_conflict(self.prefix, ignore=ignore_files)
if conflict:
raise ExtensionConflictError(conflict)
- tree.merge(self.prefix, ignore=spack.install_layout.hidden_file_paths)
+ tree.merge(self.prefix, ignore=ignore_files)
def do_deactivate(self):
+ """Called on the extension to invoke extendee's deactivate() method."""
self._sanity_check_extension()
- self.extendee_spec.package.deactivate(self)
+ self.extendee_spec.package.deactivate(self, **self.extendee_args)
if self.spec in spack.install_layout.get_extensions(self.extendee_spec):
spack.install_layout.remove_extension(self.extendee_spec, self.spec)
@@ -1002,7 +1017,7 @@ class Package(object):
% (self.spec.short_spec, self.extendee_spec.short_spec))
- def deactivate(self, extension):
+ def deactivate(self, extension, **kwargs):
"""Unlinks all files from extension out of this package's install dir.
Package authors can override this method to support other
@@ -1011,8 +1026,11 @@ class Package(object):
always executed.
"""
+ ignore_files = set(spack.install_layout.hidden_file_paths)
+ ignore_files.update(kwargs.get('ignore', ()))
+
tree = LinkTree(extension.prefix)
- tree.unmerge(self.prefix, ignore=spack.install_layout.hidden_file_paths)
+ tree.unmerge(self.prefix, ignore=ignore_files)
def do_clean(self):
diff --git a/lib/spack/spack/relations.py b/lib/spack/spack/relations.py
index 60ff5bef34..a0c7723473 100644
--- a/lib/spack/spack/relations.py
+++ b/lib/spack/spack/relations.py
@@ -117,7 +117,7 @@ def depends_on(*specs):
dependencies[spec.name] = spec
-def extends(*specs):
+def extends(spec, **kwargs):
"""Same as depends_on, but dependency is symlinked into parent prefix.
This is for Python and other language modules where the module
@@ -126,6 +126,10 @@ def extends(*specs):
but allowing ONE module version to be symlinked into a parent
Python install at a time.
+ keyword arguments can be passed to extends() so that extension
+ packages can pass parameters to the extendee's extension
+ mechanism.
+
"""
pkg = get_calling_package_name()
clocals = caller_locals()
@@ -134,12 +138,11 @@ def extends(*specs):
if extendees:
raise RelationError("Packages can extend at most one other package.")
- for string in specs:
- for spec in spack.spec.parse(string):
- if pkg == spec.name:
- raise CircularReferenceError('extends', pkg)
- dependencies[spec.name] = spec
- extendees[spec.name] = spec
+ spec = Spec(spec)
+ if pkg == spec.name:
+ raise CircularReferenceError('extends', pkg)
+ dependencies[spec.name] = spec
+ extendees[spec.name] = (spec, kwargs)
def provides(*specs, **kwargs):
diff --git a/var/spack/packages/python/package.py b/var/spack/packages/python/package.py
index 9700179ab8..86b903bc23 100644
--- a/var/spack/packages/python/package.py
+++ b/var/spack/packages/python/package.py
@@ -28,6 +28,16 @@ class Python(Package):
make("install")
+ @property
+ def python_lib_dir(self):
+ return os.path.join('lib', 'python%d.%d' % self.version[:2])
+
+
+ @property
+ def site_packages_dir(self):
+ return os.path.join(self.python_lib_dir, 'site-packages')
+
+
def setup_extension_environment(self, module, spec, ext_spec):
"""Called before python modules' install() methods.
@@ -39,11 +49,29 @@ class Python(Package):
module.python = Executable(join_path(spec.prefix.bin, 'python'))
# Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs.
- module.python_lib_dir = join_path(ext_spec.prefix.lib, 'python%d.%d' % self.version[:2])
- module.site_packages_dir = join_path(module.python_lib_dir, 'site-packages')
+ module.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir)
+ module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir)
# Add site packages directory to the PYTHONPATH
os.environ['PYTHONPATH'] = module.site_packages_dir
# Make the site packages directory if it does not exist already.
mkdirp(module.site_packages_dir)
+
+
+ def add_ignore_files(self, args):
+ """Add some ignore files to activate/deactivate args."""
+ ignore = set(args.get('ignore', ()))
+ ignore.add(os.path.join(self.site_packages_dir, 'site.py'))
+ ignore.add(os.path.join(self.site_packages_dir, 'site.pyc'))
+ args.update(ignore=ignore)
+
+
+ def activate(self, ext_pkg, **args):
+ self.add_ignore_files(args)
+ super(Python, self).activate(ext_pkg, **args)
+
+
+ def deactivate(self, ext_pkg, **args):
+ self.add_ignore_files(args)
+ super(Python, self).deactivate(ext_pkg, **args)