Bugfixes, more consolidation of modules code.

- specific module classes use __metaclass__ to register themselves.
- bugfixes in module writing.
This commit is contained in:
Todd Gamblin 2014-08-16 22:22:34 -07:00
parent 776560f8ce
commit 22bec329c1
4 changed files with 50 additions and 21 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@
.idea
/etc/spackconfig
/share/spack/dotkit
/share/spack/modules

View file

@ -32,18 +32,13 @@
from llnl.util.filesystem import mkdirp
import spack.cmd
import spack.modules
from spack.modules import module_types
from spack.util.string import *
from spack.spec import Spec
description ="Manipulate modules and dotkits."
module_types = {
'dotkit' : spack.modules.Dotkit,
'tcl' : spack.modules.TclModule
}
def setup_parser(subparser):
sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='module_command')
@ -87,13 +82,19 @@ def module_find(mtype, spec_array):
def module_refresh():
shutil.rmtree(spack.dotkit_path, ignore_errors=False)
mkdirp(spack.dotkit_path)
"""Regenerate all module files for installed packages known to
spack (some packages may no longer exist)."""
specs = [s for s in spack.db.installed_known_package_specs()]
specs = spack.db.installed_package_specs()
for name, cls in module_types.items():
tty.msg("Regenerating %s module files." % name)
if os.path.isdir(cls.path):
shutil.rmtree(cls.path, ignore_errors=False)
mkdirp(cls.path)
for spec in specs:
for mt in module_types:
mt(spec.package).write()
tty.debug(" Writing file for %s." % spec)
cls(spec.package).write()
def module(parser, args):

View file

@ -56,8 +56,10 @@
import spack
dotkit_path = join_path(spack.share_path, "dotkit")
tcl_mod_path = join_path(spack.share_path, "modules")
"""Registry of all types of modules. Entries created by EnvModule's
metaclass."""
module_types = {}
def print_help():
"""For use by commands to tell user how to activate shell support."""
@ -77,6 +79,15 @@ def print_help():
class EnvModule(object):
name = 'env_module'
class __metaclass__(type):
def __init__(cls, name, bases, dict):
type.__init__(cls, name, bases, dict)
if cls.name != 'env_module':
module_types[cls.name] = cls
def __init__(self, pkg=None):
# category in the modules system
# TODO: come up with smarter category names.
@ -97,7 +108,7 @@ def paths(self):
if self._paths is None:
self._paths = {}
def add_path(self, path_name, directory):
def add_path(path_name, directory):
path = self._paths.setdefault(path_name, [])
path.append(directory)
@ -126,14 +137,14 @@ def add_path(self, path_name, directory):
def write(self):
"""Write out a module file for this object."""
module_dir = os.path.dirname(self.file_name)
if not os.path.exists():
if not os.path.exists(module_dir):
mkdirp(module_dir)
# If there are no paths, no need for a dotkit.
if not self.paths:
return
with closing(open(self.file_name)) as f:
with closing(open(self.file_name, 'w')) as f:
self._write(f)
@ -156,10 +167,13 @@ def remove(self):
class Dotkit(EnvModule):
name = 'dotkit'
path = join_path(spack.share_path, "dotkit")
@property
def file_name(self):
spec = self.pkg.spec
return join_path(dotkit_path, spec.architecture,
return join_path(Dotkit.path, spec.architecture,
spec.format('$_$@$%@$+$#.dk'))
@ -183,14 +197,17 @@ def _write(self, dk_file):
dk_file.write("dk_alter %s %s\n" % (var, directory))
# Let CMake find this package.
dk_file.write("dk_alter CMAKE_PREFIX_PATH %s\n" % pkg.prefix)
dk_file.write("dk_alter CMAKE_PREFIX_PATH %s\n" % self.pkg.prefix)
class TclModule(EnvModule):
name = 'tcl'
path = join_path(spack.share_path, "modules")
@property
def file_name(self):
spec = self.pkg.spec
return join_path(tcl_mod_path, spec.architecture,
return join_path(TclModule.path, spec.architecture,
spec.format('$_$@$%@$+$#'))
@ -214,4 +231,4 @@ def _write(self, m_file):
for directory in dirs:
m_file.write("prepend-path %s \"%s\"\n" % (var, directory))
m_file.write("prepend-path CMAKE_PREFIX_PATH \"%s\"\n" % pkg.prefix)
m_file.write("prepend-path CMAKE_PREFIX_PATH \"%s\"\n" % self.pkg.prefix)

View file

@ -118,6 +118,16 @@ def installed_package_specs(self):
return spack.install_layout.all_specs()
def installed_known_package_specs(self):
"""Read installed package names straight from the install
directory layout, but return only specs for which the
package is known to this version of spack.
"""
for spec in spack.install_layout.all_specs():
if self.exists(spec.name):
yield spec
@memoized
def all_package_names(self):
"""Generator function for all packages. This looks for