Add arguements to extends() and activate/deactivate.

This commit is contained in:
Todd Gamblin 2015-01-20 00:23:16 -08:00
parent 9fa489b7f2
commit ff9cb94f4f
3 changed files with 69 additions and 20 deletions

View File

@ -497,16 +497,26 @@ def fetcher(self, f):
@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 @@ def _check_extendable(self):
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 @@ def do_activate(self):
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 @@ def activate(self, extension):
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 @@ def do_deactivate(self):
% (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 @@ def deactivate(self, extension):
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):

View File

@ -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):

View File

@ -28,6 +28,16 @@ def install(self, spec, prefix):
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 @@ def setup_extension_environment(self, module, spec, ext_spec):
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)