summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2015-01-06 14:47:51 -0500
committerTodd Gamblin <tgamblin@llnl.gov>2015-02-02 11:16:23 -0800
commit88afad3e46326c56aaeaed6adc2058033ad7ad33 (patch)
tree798c5c168be1fde346350b16487d6ad3473606bd /lib
parentba593ccb260e46568fc2620ad5f300f89495a604 (diff)
downloadspack-88afad3e46326c56aaeaed6adc2058033ad7ad33.tar.gz
spack-88afad3e46326c56aaeaed6adc2058033ad7ad33.tar.bz2
spack-88afad3e46326c56aaeaed6adc2058033ad7ad33.tar.xz
spack-88afad3e46326c56aaeaed6adc2058033ad7ad33.zip
Directory layout can now track installed extensions per package.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/directory_layout.py97
1 files changed, 96 insertions, 1 deletions
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 42cac0c9d2..4ab9a515cf 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -71,6 +71,21 @@ class DirectoryLayout(object):
raise NotImplementedError()
+ def get_extensions(self, spec):
+ """Get a set of currently installed extension packages for a spec."""
+ raise NotImplementedError()
+
+
+ def add_extension(self, spec, extension_spec):
+ """Add to the list of currently installed extensions."""
+ raise NotImplementedError()
+
+
+ def remove_extension(self, spec, extension_spec):
+ """Remove from the list of currently installed extensions."""
+ raise NotImplementedError()
+
+
def path_for_spec(self, spec):
"""Return an absolute path from the root to a directory for the spec."""
_check_concrete(spec)
@@ -134,9 +149,11 @@ class SpecHashDirectoryLayout(DirectoryLayout):
"""Prefix size is number of characters in the SHA-1 prefix to use
to make each hash unique.
"""
- spec_file_name = kwargs.get('spec_file_name', '.spec')
+ spec_file_name = kwargs.get('spec_file_name', '.spec')
+ extension_file_name = kwargs.get('extension_file_name', '.extensions')
super(SpecHashDirectoryLayout, self).__init__(root)
self.spec_file_name = spec_file_name
+ self.extension_file_name = extension_file_name
def relative_path_for_spec(self, spec):
@@ -225,6 +242,55 @@ class SpecHashDirectoryLayout(DirectoryLayout):
yield spec
+ def extension_file_path(self, spec):
+ """Gets full path to an installed package's extension file"""
+ _check_concrete(spec)
+ return join_path(self.path_for_spec(spec), self.extension_file_name)
+
+
+ def get_extensions(self, spec):
+ path = self.extension_file_path(spec)
+
+ extensions = set()
+ if os.path.exists(path):
+ with closing(open(path)) as spec_file:
+ for line in spec_file:
+ try:
+ extensions.add(Spec(line))
+ except SpecError, e:
+ raise InvalidExtensionSpecError(str(e))
+ return extensions
+
+
+ def write_extensions(self, extensions):
+ path = self.extension_file_path(spec)
+ with closing(open(path, 'w')) as spec_file:
+ for extension in sorted(extensions):
+ spec_file.write("%s\n" % extensions)
+
+
+ def add_extension(self, spec, extension_spec):
+ exts = get_extensions(spec)
+ if extension_spec in exts:
+ raise ExtensionAlreadyInstalledError(spec, extension_spec)
+ else:
+ for already_installed in exts:
+ if spec.name == extension_spec.name:
+ raise ExtensionConflictError(spec, extension_spec, already_installed)
+
+ exts.add(extension_spec)
+ self.write_extensions(exts)
+
+
+ def remove_extension(self, spec, extension_spec):
+ exts = get_extensions(spec)
+ if not extension_spec in exts:
+ raise NoSuchExtensionError(spec, extension_spec)
+
+ exts.remove(extension_spec)
+ self.write_extensions(exts)
+
+
class DirectoryLayoutError(SpackError):
"""Superclass for directory layout errors."""
def __init__(self, message):
@@ -250,3 +316,32 @@ class InstallDirectoryAlreadyExistsError(DirectoryLayoutError):
def __init__(self, path):
super(InstallDirectoryAlreadyExistsError, self).__init__(
"Install path %s already exists!")
+
+
+class InvalidExtensionSpecError(DirectoryLayoutError):
+ """Raised when an extension file has a bad spec in it."""
+ def __init__(self, message):
+ super(InvalidExtensionSpecError, self).__init__(message)
+
+
+class ExtensionAlreadyInstalledError(DirectoryLayoutError):
+ """Raised when an extension is added to a package that already has it."""
+ def __init__(self, spec, extension_spec):
+ super(ExtensionAlreadyInstalledError, self).__init__(
+ "%s is already installed in %s" % (extension_spec, spec))
+
+
+class ExtensionConflictError(DirectoryLayoutError):
+ """Raised when an extension is added to a package that already has it."""
+ def __init__(self, spec, extension_spec, conflict):
+ super(ExtensionConflictError, self).__init__(
+ "%s cannot be installed in %s because it conflicts with %s."% (
+ extension_spec, spec, conflict))
+
+
+class NoSuchExtensionError(DirectoryLayoutError):
+ """Raised when an extension isn't there on remove."""
+ def __init__(self, spec, extension_spec):
+ super(NoSuchExtensionError, self).__init__(
+ "%s cannot be removed from %s beacuse it's not installed."% (
+ extension_spec, spec, conflict))