summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralalazo <massimiliano.culpo@googlemail.com>2016-04-06 13:42:47 +0200
committeralalazo <massimiliano.culpo@googlemail.com>2016-04-06 13:42:47 +0200
commitd636b4fdde5b9a37dff9a354368d36fa6969cec9 (patch)
treecf4cdf6b851f9485b7e291e9daacb291de325d1e
parent670cb423f91b17b9757b387a9579be4f248d208b (diff)
downloadspack-d636b4fdde5b9a37dff9a354368d36fa6969cec9.tar.gz
spack-d636b4fdde5b9a37dff9a354368d36fa6969cec9.tar.bz2
spack-d636b4fdde5b9a37dff9a354368d36fa6969cec9.tar.xz
spack-d636b4fdde5b9a37dff9a354368d36fa6969cec9.zip
modules : more sensible name to blacklist environment variables
modules : added skeleton to permit modifications based on specs
-rw-r--r--lib/spack/spack/config.py20
-rw-r--r--lib/spack/spack/environment.py2
-rw-r--r--lib/spack/spack/modules.py90
3 files changed, 62 insertions, 50 deletions
diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py
index ff5fba24f8..2067c6146e 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -250,7 +250,7 @@ section_schemas = {
'type': 'string',
'enum': ['None', 'Direct', 'All']
},
- 'module_type_configuration': {
+ 'module_file_configuration': {
'type': 'object',
'default': {},
'additionalProperties': False,
@@ -260,7 +260,7 @@ section_schemas = {
'default': {},
'additionalProperties': False,
'properties': {
- 'environment_modifications': {
+ 'environment_blacklist': {
'type': 'array',
'default': [],
'items': {
@@ -270,7 +270,21 @@ section_schemas = {
}
},
'autoload': {'$ref': '#/definitions/dependency_selection'},
- 'prerequisites': {'$ref': '#/definitions/dependency_selection'}
+ 'prerequisites': {'$ref': '#/definitions/dependency_selection'},
+ 'environment': {
+ 'type': 'object',
+ 'default': {}
+ }
+ }
+ },
+ 'module_type_configuration': {
+ 'type': 'object',
+ 'default': {},
+ 'properties': {
+ 'all': {'$ref': '#/definitions/module_file_configuration'}
+ },
+ 'patternProperties': {
+ r'\w[\w-]*': {'$ref': '#/definitions/module_file_configuration'}
}
}
},
diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 3d18d3a63f..92ab4e6bea 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -252,7 +252,7 @@ def validate(env, errstream):
set_or_unset_not_first(variable, list_of_changes, errstream)
-def filter_environment_modifications(env, variables):
+def filter_environment_blacklist(env, variables):
"""
Generator that filters out any change to environment variables present in the input list
diff --git a/lib/spack/spack/modules.py b/lib/spack/spack/modules.py
index 115d4d9a37..62cd2a8a8b 100644
--- a/lib/spack/spack/modules.py
+++ b/lib/spack/spack/modules.py
@@ -49,6 +49,7 @@ import textwrap
import llnl.util.tty as tty
import spack
import spack.config
+
from llnl.util.filesystem import join_path, mkdirp
from spack.build_environment import parent_class_modules, set_module_variables_for_package
from spack.environment import *
@@ -137,7 +138,6 @@ class EnvModule(object):
if self.spec.package.__doc__:
self.long_description = re.sub(r'\s+', ' ', self.spec.package.__doc__)
-
@property
def category(self):
# Anything defined at the package level takes precedence
@@ -150,35 +150,40 @@ class EnvModule(object):
return 'spack installed package'
def write(self):
- """Write out a module file for this object."""
+ """
+ Writes out a module file for this object.
+
+ This method employs a template pattern and expects derived classes to:
+ - override the header property
+ - provide formats for autoload, prerequisites and environment changes
+ """
module_dir = os.path.dirname(self.file_name)
if not os.path.exists(module_dir):
mkdirp(module_dir)
- # Environment modifications guessed by inspecting the
- # installation prefix
- env = inspect_path(self.spec.prefix)
-
- # Let the extendee/dependency modify their extensions/dependencies before asking for
- # package-specific modifications
- spack_env = EnvironmentModifications()
-
def dependencies(request='All'):
if request == 'None':
return []
- l = [x for x in sorted(self.spec.traverse(order='post', depth=True, cover='nodes', root=False), reverse=True)]
+ l = [xx for xx in sorted(self.spec.traverse(order='post', depth=True, cover='nodes', root=False), reverse=True)]
if request == 'Direct':
- return [x for ii, x in l if ii == 1]
+ return [xx for ii, xx in l if ii == 1]
# FIXME : during module file creation nodes seem to be visited multiple times even if cover='nodes'
# FIXME : is given. This work around permits to get a unique list of spec anyhow.
# FIXME : Possibly we miss a merge step among nodes that refer to the same package.
seen = set()
seen_add = seen.add
- return [x for ii, x in l if not (x in seen or seen_add(x))]
+ return [xx for ii, xx in l if not (xx in seen or seen_add(xx))]
+
+ # Environment modifications guessed by inspecting the
+ # installation prefix
+ env = inspect_path(self.spec.prefix)
+ # Let the extendee/dependency modify their extensions/dependencies before asking for
+ # package-specific modifications
+ spack_env = EnvironmentModifications()
# TODO : the code down below is quite similar to build_environment.setup_package and needs to be
# TODO : factored out to a single place
for item in dependencies('All'):
@@ -207,43 +212,43 @@ class EnvModule(object):
# Filter modifications to environment variables
try:
- filter_list = CONFIGURATION[self.name]['filter']['environment_modifications']
+ filter_list = CONFIGURATION[self.name]['filter']['environment_blacklist']
except KeyError:
filter_list = []
+ # Build up the module file content
+ module_file_content = self.header
+ for x in autoload_list:
+ module_file_content += self.autoload(x)
+ for x in prerequisites_list:
+ module_file_content += self.prerequisite(x)
+ for line in self.process_environment_command(filter_environment_blacklist(env, filter_list)):
+ module_file_content += line
+
+ # Dump to file
with open(self.file_name, 'w') as f:
- # Header
- f.write(self.header)
- # Automatic loads
- for x in autoload_list:
- f.write(self.autoload(x))
- # Prerequisites
- for x in prerequisites_list:
- f.write(self.prerequisite(x))
- # Modifications to the environment
- iterable = self.process_environment_command(filter_environment_modifications(env, filter_list))
- for line in iterable:
- f.write(line)
+ f.write(module_file_content)
@property
def header(self):
raise NotImplementedError()
def autoload(self, spec):
- raise NotImplementedError()
+ m = TclModule(spec)
+ return self.autoload_format.format(module_file=m.use_name)
def prerequisite(self, spec):
- raise NotImplementedError()
+ m = TclModule(spec)
+ return self.prerequisite_format.format(module_file=m.use_name)
def process_environment_command(self, env):
for command in env:
try:
- yield self.formats[type(command)].format(**command.args)
+ yield self.environment_modifications_formats[type(command)].format(**command.args)
except KeyError:
tty.warn('Cannot handle command of type {command} : skipping request'.format(command=type(command)))
tty.warn('{context} at {filename}:{lineno}'.format(**command.args))
-
@property
def file_name(self):
"""Subclasses should implement this to return the name of the file
@@ -266,7 +271,7 @@ class Dotkit(EnvModule):
name = 'dotkit'
path = join_path(spack.share_path, "dotkit")
- formats = {
+ environment_modifications_formats = {
PrependPath: 'dk_alter {name} {value}\n',
SetEnv: 'dk_setenv {name} {value}\n'
}
@@ -304,7 +309,7 @@ class TclModule(EnvModule):
name = 'tcl'
path = join_path(spack.share_path, "modules")
- formats = {
+ environment_modifications_formats = {
PrependPath: 'prepend-path {name} \"{value}\"\n',
AppendPath: 'append-path {name} \"{value}\"\n',
RemovePath: 'remove-path {name} \"{value}\"\n',
@@ -312,6 +317,13 @@ class TclModule(EnvModule):
UnsetEnv: 'unsetenv {name}\n'
}
+ autoload_format = ('if ![ is-loaded {module_file} ] {{'
+ ' puts stderr "Autoloading {module_file}"'
+ ' module load {module_file}'
+ '}}')
+
+ prerequisite_format = 'prereq {module_file}\n'
+
@property
def file_name(self):
return join_path(TclModule.path, self.spec.architecture, self.use_name)
@@ -339,17 +351,3 @@ class TclModule(EnvModule):
header += 'puts stderr "%s"\n' % line
header += '}\n\n'
return header
-
- def autoload(self, spec):
- autoload_format = '''
-if ![ is-loaded {module_file} ] {{
- puts stderr "Autoloading {module_file}"
- module load {module_file}
-}}
-'''''
- m = TclModule(spec)
- return autoload_format.format(module_file=m.use_name)
-
- def prerequisite(self, spec):
- m = TclModule(spec)
- return 'prereq {module_file}\n'.format(module_file=m.use_name)