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 @property
def extendee_spec(self): def extendee_spec(self):
"""Spec of the extendee of this package, or None if it is not an extension.""" """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)) name = next(iter(self.extendees))
if not name in self.spec: 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 # Need to do this to get the concrete version of the spec
return self.spec[name] 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 @property
def is_extension(self): def is_extension(self):
return len(self.extendees) > 0 return len(self.extendees) > 0
@ -949,6 +959,8 @@ def _check_extendable(self):
def _sanity_check_extension(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 = self.extendee_spec.package
extendee_package._check_extendable() extendee_package._check_extendable()
@ -967,14 +979,14 @@ def do_activate(self):
activate() directly. activate() directly.
""" """
self._sanity_check_extension() 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) spack.install_layout.add_extension(self.extendee_spec, self.spec)
tty.msg("Activated extension %s for %s." tty.msg("Activated extension %s for %s."
% (self.spec.short_spec, self.extendee_spec.short_spec)) % (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. """Symlinks all files from the extension into extendee's install dir.
Package authors can override this method to support other Package authors can override this method to support other
@ -983,17 +995,20 @@ def activate(self, extension):
always executed. always executed.
""" """
ignore_files = set(spack.install_layout.hidden_file_paths)
ignore_files.update(kwargs.get('ignore', ()))
tree = LinkTree(extension.prefix) tree = LinkTree(extension.prefix)
conflict = tree.find_conflict( conflict = tree.find_conflict(self.prefix, ignore=ignore_files)
self.prefix, ignore=spack.install_layout.hidden_file_paths)
if conflict: if conflict:
raise ExtensionConflictError(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): def do_deactivate(self):
"""Called on the extension to invoke extendee's deactivate() method."""
self._sanity_check_extension() 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): if self.spec in spack.install_layout.get_extensions(self.extendee_spec):
spack.install_layout.remove_extension(self.extendee_spec, self.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)) % (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. """Unlinks all files from extension out of this package's install dir.
Package authors can override this method to support other Package authors can override this method to support other
@ -1011,8 +1026,11 @@ def deactivate(self, extension):
always executed. always executed.
""" """
ignore_files = set(spack.install_layout.hidden_file_paths)
ignore_files.update(kwargs.get('ignore', ()))
tree = LinkTree(extension.prefix) 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): def do_clean(self):

View File

@ -117,7 +117,7 @@ def depends_on(*specs):
dependencies[spec.name] = spec dependencies[spec.name] = spec
def extends(*specs): def extends(spec, **kwargs):
"""Same as depends_on, but dependency is symlinked into parent prefix. """Same as depends_on, but dependency is symlinked into parent prefix.
This is for Python and other language modules where the module 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 but allowing ONE module version to be symlinked into a parent
Python install at a time. 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() pkg = get_calling_package_name()
clocals = caller_locals() clocals = caller_locals()
@ -134,12 +138,11 @@ def extends(*specs):
if extendees: if extendees:
raise RelationError("Packages can extend at most one other package.") raise RelationError("Packages can extend at most one other package.")
for string in specs: spec = Spec(spec)
for spec in spack.spec.parse(string): if pkg == spec.name:
if pkg == spec.name: raise CircularReferenceError('extends', pkg)
raise CircularReferenceError('extends', pkg) dependencies[spec.name] = spec
dependencies[spec.name] = spec extendees[spec.name] = (spec, kwargs)
extendees[spec.name] = spec
def provides(*specs, **kwargs): def provides(*specs, **kwargs):

View File

@ -28,6 +28,16 @@ def install(self, spec, prefix):
make("install") 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): def setup_extension_environment(self, module, spec, ext_spec):
"""Called before python modules' install() methods. """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')) module.python = Executable(join_path(spec.prefix.bin, 'python'))
# Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs. # 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.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir)
module.site_packages_dir = join_path(module.python_lib_dir, 'site-packages') module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir)
# Add site packages directory to the PYTHONPATH # Add site packages directory to the PYTHONPATH
os.environ['PYTHONPATH'] = module.site_packages_dir os.environ['PYTHONPATH'] = module.site_packages_dir
# Make the site packages directory if it does not exist already. # Make the site packages directory if it does not exist already.
mkdirp(module.site_packages_dir) 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)