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:
		 Oliver Breitwieser
					Oliver Breitwieser
				
			
				
					committed by
					
						 scheibelp
						scheibelp
					
				
			
			
				
	
			
			
			 scheibelp
						scheibelp
					
				
			
						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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user