views: support querying view layouts as well
This abstracts out the layout in use between the global installations and a specific view.
This commit is contained in:
parent
00a893aa79
commit
078f85a125
@ -100,9 +100,9 @@ def extensions(parser, args):
|
|||||||
spack.cmd.find.display_specs(installed, mode=args.mode)
|
spack.cmd.find.display_specs(installed, mode=args.mode)
|
||||||
|
|
||||||
#
|
#
|
||||||
# List specs of activated extensions.
|
# List specs of globally activated extensions.
|
||||||
#
|
#
|
||||||
activated = spack.store.layout.extension_map(spec)
|
activated = spack.store.extensions.extension_map(spec)
|
||||||
print
|
print
|
||||||
if not activated:
|
if not activated:
|
||||||
tty.msg("None activated.")
|
tty.msg("None activated.")
|
||||||
|
@ -751,14 +751,16 @@ def installed_extensions_for(self, extendee_spec):
|
|||||||
yield spec.package
|
yield spec.package
|
||||||
|
|
||||||
@_autospec
|
@_autospec
|
||||||
def activated_extensions_for(self, extendee_spec):
|
def activated_extensions_for(self, extendee_spec, extensions_layout=None):
|
||||||
"""
|
"""
|
||||||
Return the specs of all packages that extend
|
Return the specs of all packages that extend
|
||||||
the given spec
|
the given spec
|
||||||
"""
|
"""
|
||||||
|
if extensions_layout is None:
|
||||||
|
extensions_layout = spack.store.extensions
|
||||||
for spec in self.query():
|
for spec in self.query():
|
||||||
try:
|
try:
|
||||||
spack.store.layout.check_activated(extendee_spec, spec)
|
extensions_layout.check_activated(extendee_spec, spec)
|
||||||
yield spec.package
|
yield spec.package
|
||||||
except spack.directory_layout.NoSuchExtensionError:
|
except spack.directory_layout.NoSuchExtensionError:
|
||||||
continue
|
continue
|
||||||
|
@ -30,4 +30,5 @@ def pre_uninstall(spec):
|
|||||||
|
|
||||||
if pkg.is_extension:
|
if pkg.is_extension:
|
||||||
if pkg.is_activated():
|
if pkg.is_activated():
|
||||||
|
# deactivate globally
|
||||||
pkg.do_deactivate(force=True)
|
pkg.do_deactivate(force=True)
|
||||||
|
@ -903,12 +903,14 @@ def extends(self, spec):
|
|||||||
s = self.extendee_spec
|
s = self.extendee_spec
|
||||||
return s and spec.satisfies(s)
|
return s and spec.satisfies(s)
|
||||||
|
|
||||||
def is_activated(self):
|
def is_activated(self, extensions_layout=None):
|
||||||
"""Return True if package is activated."""
|
"""Return True if package is activated."""
|
||||||
if not self.is_extension:
|
if not self.is_extension:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"is_extension called on package that is not an extension.")
|
"is_extension called on package that is not an extension.")
|
||||||
exts = spack.store.layout.extension_map(self.extendee_spec)
|
if extensions_layout is None:
|
||||||
|
extensions_layout = spack.store.extensions
|
||||||
|
exts = extensions_layout.extension_map(self.extendee_spec)
|
||||||
return (self.name in exts) and (exts[self.name] == self.spec)
|
return (self.name in exts) and (exts[self.name] == self.spec)
|
||||||
|
|
||||||
def provides(self, vpkg_name):
|
def provides(self, vpkg_name):
|
||||||
@ -1773,7 +1775,7 @@ def _sanity_check_extension(self):
|
|||||||
raise ActivationError("%s does not extend %s!" %
|
raise ActivationError("%s does not extend %s!" %
|
||||||
(self.name, self.extendee.name))
|
(self.name, self.extendee.name))
|
||||||
|
|
||||||
def do_activate(self, force=False, verbose=True):
|
def do_activate(self, force=False, verbose=True, extensions_layout=None):
|
||||||
"""Called on an extension to invoke the extendee's activate method.
|
"""Called on an extension to invoke the extendee's activate method.
|
||||||
|
|
||||||
Commands should call this routine, and should not call
|
Commands should call this routine, and should not call
|
||||||
@ -1781,18 +1783,25 @@ def do_activate(self, force=False, verbose=True):
|
|||||||
"""
|
"""
|
||||||
self._sanity_check_extension()
|
self._sanity_check_extension()
|
||||||
|
|
||||||
spack.store.layout.check_extension_conflict(
|
if extensions_layout is None:
|
||||||
|
extensions_layout = spack.store.extensions
|
||||||
|
|
||||||
|
extensions_layout.check_extension_conflict(
|
||||||
self.extendee_spec, self.spec)
|
self.extendee_spec, self.spec)
|
||||||
|
|
||||||
# Activate any package dependencies that are also extensions.
|
# Activate any package dependencies that are also extensions.
|
||||||
if not force:
|
if not force:
|
||||||
for spec in self.dependency_activations():
|
for spec in self.dependency_activations():
|
||||||
if not spec.package.is_activated():
|
if not spec.package.is_activated(
|
||||||
spec.package.do_activate(force=force, verbose=verbose)
|
extensions_layout=extensions_layout):
|
||||||
|
spec.package.do_activate(
|
||||||
|
force=force, verbose=verbose,
|
||||||
|
extensions_layout=extensions_layout)
|
||||||
|
|
||||||
self.extendee_spec.package.activate(self, **self.extendee_args)
|
self.extendee_spec.package.activate(
|
||||||
|
self, extensions_layout=extensions_layout, **self.extendee_args)
|
||||||
|
|
||||||
spack.store.layout.add_extension(self.extendee_spec, self.spec)
|
extensions_layout.add_extension(self.extendee_spec, self.spec)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
tty.msg(
|
tty.msg(
|
||||||
@ -1805,7 +1814,9 @@ def dependency_activations(self):
|
|||||||
if spec.package.extends(self.extendee_spec))
|
if spec.package.extends(self.extendee_spec))
|
||||||
|
|
||||||
def activate(self, extension, **kwargs):
|
def activate(self, extension, **kwargs):
|
||||||
"""Symlinks all files from the extension into extendee's install dir.
|
"""Make extension package usable by linking all its files to a target
|
||||||
|
provided by the directory layout (depending if the user wants to
|
||||||
|
activate globally or in a specified file system view).
|
||||||
|
|
||||||
Package authors can override this method to support other
|
Package authors can override this method to support other
|
||||||
extension mechanisms. Spack internals (commands, hooks, etc.)
|
extension mechanisms. Spack internals (commands, hooks, etc.)
|
||||||
@ -1813,48 +1824,57 @@ def activate(self, extension, **kwargs):
|
|||||||
always executed.
|
always executed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
extensions_layout = kwargs.get("extensions_layout",
|
||||||
|
spack.store.extensions)
|
||||||
|
target = extensions_layout.extendee_target_directory(self)
|
||||||
|
|
||||||
def ignore(filename):
|
def ignore(filename):
|
||||||
return (filename in spack.store.layout.hidden_file_paths or
|
return (filename in spack.store.layout.hidden_file_paths or
|
||||||
kwargs.get('ignore', lambda f: False)(filename))
|
kwargs.get('ignore', lambda f: False)(filename))
|
||||||
|
|
||||||
tree = LinkTree(extension.prefix)
|
tree = LinkTree(extension.prefix)
|
||||||
conflict = tree.find_conflict(self.prefix, ignore=ignore)
|
conflict = tree.find_conflict(target, ignore=ignore)
|
||||||
if conflict:
|
if conflict:
|
||||||
raise ExtensionConflictError(conflict)
|
raise ExtensionConflictError(conflict)
|
||||||
|
|
||||||
tree.merge(self.prefix, ignore=ignore)
|
tree.merge(target, ignore=ignore, link=extensions_layout.link)
|
||||||
|
|
||||||
def do_deactivate(self, **kwargs):
|
def do_deactivate(self, **kwargs):
|
||||||
"""Called on the extension to invoke extendee's deactivate() method."""
|
"""Called on the extension to invoke extendee's deactivate() method."""
|
||||||
self._sanity_check_extension()
|
self._sanity_check_extension()
|
||||||
force = kwargs.get('force', False)
|
force = kwargs.get('force', False)
|
||||||
verbose = kwargs.get("verbose", True)
|
verbose = kwargs.get("verbose", True)
|
||||||
|
extensions_layout = kwargs.get("extensions_layout",
|
||||||
|
spack.store.extensions)
|
||||||
|
|
||||||
# Allow a force deactivate to happen. This can unlink
|
# Allow a force deactivate to happen. This can unlink
|
||||||
# spurious files if something was corrupted.
|
# spurious files if something was corrupted.
|
||||||
if not force:
|
if not force:
|
||||||
spack.store.layout.check_activated(
|
extensions_layout.check_activated(
|
||||||
self.extendee_spec, self.spec)
|
self.extendee_spec, self.spec)
|
||||||
|
|
||||||
activated = spack.store.layout.extension_map(
|
activated = extensions_layout.extension_map(
|
||||||
self.extendee_spec)
|
self.extendee_spec)
|
||||||
for name, aspec in activated.items():
|
for name, aspec in activated.items():
|
||||||
if aspec == self.spec:
|
if aspec == self.spec:
|
||||||
continue
|
continue
|
||||||
for dep in aspec.traverse(deptype='run'):
|
for dep in aspec.traverse(deptype='run'):
|
||||||
if self.spec == dep:
|
if self.spec == dep:
|
||||||
msg = ("Cannot deactivate %s because %s is activated "
|
msg = ("Cannot deactivate %s because %s is "
|
||||||
"and depends on it.")
|
"activated and depends on it.")
|
||||||
raise ActivationError(
|
raise ActivationError(
|
||||||
msg % (self.spec.short_spec, aspec.short_spec))
|
msg % (self.spec.cshort_spec,
|
||||||
|
aspec.cshort_spec))
|
||||||
|
|
||||||
self.extendee_spec.package.deactivate(self, **self.extendee_args)
|
self.extendee_spec.package.deactivate(
|
||||||
|
self,
|
||||||
|
extensions_layout=extensions_layout,
|
||||||
|
**self.extendee_args)
|
||||||
|
|
||||||
# redundant activation check -- makes SURE the spec is not
|
# redundant activation check -- makes SURE the spec is not
|
||||||
# still activated even if something was wrong above.
|
# still activated even if something was wrong above.
|
||||||
if self.is_activated():
|
if self.is_activated(extensions_layout):
|
||||||
spack.store.layout.remove_extension(
|
extensions_layout.remove_extension(
|
||||||
self.extendee_spec, self.spec)
|
self.extendee_spec, self.spec)
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
@ -1864,7 +1884,8 @@ def do_deactivate(self, **kwargs):
|
|||||||
self.extendee_spec.cformat("$_$@$+$%@")))
|
self.extendee_spec.cformat("$_$@$+$%@")))
|
||||||
|
|
||||||
def deactivate(self, extension, **kwargs):
|
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
|
||||||
|
or the corresponding filesystem view.
|
||||||
|
|
||||||
Package authors can override this method to support other
|
Package authors can override this method to support other
|
||||||
extension mechanisms. Spack internals (commands, hooks, etc.)
|
extension mechanisms. Spack internals (commands, hooks, etc.)
|
||||||
@ -1872,13 +1893,16 @@ def deactivate(self, extension, **kwargs):
|
|||||||
always executed.
|
always executed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
extensions_layout = kwargs.get("extensions_layout",
|
||||||
|
spack.store.extensions)
|
||||||
|
target = extensions_layout.extendee_target_directory(self)
|
||||||
|
|
||||||
def ignore(filename):
|
def ignore(filename):
|
||||||
return (filename in spack.store.layout.hidden_file_paths or
|
return (filename in spack.store.layout.hidden_file_paths or
|
||||||
kwargs.get('ignore', lambda f: False)(filename))
|
kwargs.get('ignore', lambda f: False)(filename))
|
||||||
|
|
||||||
tree = LinkTree(extension.prefix)
|
tree = LinkTree(extension.prefix)
|
||||||
tree.unmerge(self.prefix, ignore=ignore)
|
tree.unmerge(target, ignore=ignore)
|
||||||
|
|
||||||
def do_restage(self):
|
def do_restage(self):
|
||||||
"""Reverts expanded/checked out source to a pristine state."""
|
"""Reverts expanded/checked out source to a pristine state."""
|
||||||
|
@ -48,9 +48,10 @@
|
|||||||
from spack.util.path import canonicalize_path
|
from spack.util.path import canonicalize_path
|
||||||
from spack.database import Database
|
from spack.database import Database
|
||||||
from spack.directory_layout import YamlDirectoryLayout
|
from spack.directory_layout import YamlDirectoryLayout
|
||||||
|
from spack.directory_layout import YamlExtensionsLayout
|
||||||
|
|
||||||
__author__ = "Benedikt Hegner (CERN)"
|
__author__ = "Benedikt Hegner (CERN)"
|
||||||
__all__ = ['db', 'layout', 'root']
|
__all__ = ['db', 'extensions', 'layout', 'root']
|
||||||
|
|
||||||
#
|
#
|
||||||
# Read in the config
|
# Read in the config
|
||||||
@ -75,3 +76,5 @@
|
|||||||
layout = YamlDirectoryLayout(root,
|
layout = YamlDirectoryLayout(root,
|
||||||
hash_len=config.get('install_hash_length'),
|
hash_len=config.get('install_hash_length'),
|
||||||
path_scheme=config.get('install_path_scheme'))
|
path_scheme=config.get('install_path_scheme'))
|
||||||
|
|
||||||
|
extensions = YamlExtensionsLayout(root, layout)
|
||||||
|
Loading…
Reference in New Issue
Block a user