Consolidate most module code into spack.modules and spack.cmd.module
- One file with all the module classes (spack/modules.py) - Has an EnvModule superclass that does most of the work and consolidates common code - Subclasses have specializations for different module systems (TclModule, Dotkit) - One command (spack module) for all the types of modules to use - the one command is used by the scripts, only need to maintain in one place - has some subcommands for different module types, but they're handled mostly generically. - Consolidate zsh support into a single setup-env.sh script.
This commit is contained in:
		| @@ -75,6 +75,13 @@ for cmd in spack.cmd.commands: | |||||||
|     module = spack.cmd.get_module(cmd) |     module = spack.cmd.get_module(cmd) | ||||||
|     subparser = subparsers.add_parser(cmd, help=module.description) |     subparser = subparsers.add_parser(cmd, help=module.description) | ||||||
|     module.setup_parser(subparser) |     module.setup_parser(subparser) | ||||||
|  |  | ||||||
|  | # Just print help and exit if run with no arguments at all | ||||||
|  | if len(sys.argv) == 1: | ||||||
|  |     parser.print_help() | ||||||
|  |     sys.exit(1) | ||||||
|  |  | ||||||
|  | # actually parse the args. | ||||||
| args = parser.parse_args() | args = parser.parse_args() | ||||||
|  |  | ||||||
| # Set up environment based on args. | # Set up environment based on args. | ||||||
|   | |||||||
| @@ -58,8 +58,6 @@ | |||||||
| stage_path     = join_path(var_path, "stage") | stage_path     = join_path(var_path, "stage") | ||||||
| install_path   = join_path(prefix, "opt") | install_path   = join_path(prefix, "opt") | ||||||
| share_path     = join_path(prefix, "share", "spack") | share_path     = join_path(prefix, "share", "spack") | ||||||
| dotkit_path    = join_path(share_path, "dotkit") |  | ||||||
| tclmodule_path    = join_path(share_path, "modules") |  | ||||||
|  |  | ||||||
| # | # | ||||||
| # Set up the packages database. | # Set up the packages database. | ||||||
|   | |||||||
| @@ -23,28 +23,16 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import argparse | import argparse | ||||||
| import llnl.util.tty as tty | import spack.modules | ||||||
| import spack |  | ||||||
|  |  | ||||||
| description ="Add package to environment using module." | description ="Add package to environment using modules." | ||||||
|  |  | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|  |     """Parser is only constructed so that this prints a nice help | ||||||
|  |        message with -h. """ | ||||||
|     subparser.add_argument( |     subparser.add_argument( | ||||||
|         'spec', nargs=argparse.REMAINDER, help='Spec of package to add.') |         'spec', nargs=argparse.REMAINDER, help='Spec of package to load with modules.') | ||||||
|  |  | ||||||
|  |  | ||||||
| def print_help(): |  | ||||||
|     tty.msg("Spack module support is not initialized.", |  | ||||||
|             "", |  | ||||||
|             "To use module with Spack, you must first run the command", |  | ||||||
|             "below, which you can copy and paste:", |  | ||||||
|             "", |  | ||||||
|             "For bash:", |  | ||||||
|             "    . %s/setup-env.bash" % spack.share_path, |  | ||||||
|             "", |  | ||||||
|             "ksh/csh/tcsh shells are currently unsupported", |  | ||||||
|             "") |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def load(parser, args): | def load(parser, args): | ||||||
|     print_help() |     spack.modules.print_help() | ||||||
|   | |||||||
| @@ -32,34 +32,43 @@ | |||||||
| from llnl.util.filesystem import mkdirp | from llnl.util.filesystem import mkdirp | ||||||
| 
 | 
 | ||||||
| import spack.cmd | import spack.cmd | ||||||
| import spack.hooks.dotkit | import spack.modules | ||||||
|  | from spack.util.string import * | ||||||
|  | 
 | ||||||
| from spack.spec import Spec | from spack.spec import Spec | ||||||
| 
 | 
 | ||||||
|  | description ="Manipulate modules and dotkits." | ||||||
|  | 
 | ||||||
|  | module_types = { | ||||||
|  |     'dotkit' : spack.modules.Dotkit, | ||||||
|  |     'tcl'    : spack.modules.TclModule | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| description ="Find dotkits for packages if they exist." |  | ||||||
| 
 | 
 | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|     subparser.add_argument( |     sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='module_command') | ||||||
|         '--refresh', action='store_true', help='Regenerate all dotkits') |  | ||||||
| 
 | 
 | ||||||
|     subparser.add_argument( |     refresh_parser = sp.add_parser('refresh', help='Regenerate all module files.') | ||||||
|         'spec', nargs=argparse.REMAINDER, help='spec to find a dotkit for.') | 
 | ||||||
|  |     find_parser = sp.add_parser('find', help='Find module files for packages.') | ||||||
|  |     find_parser.add_argument( | ||||||
|  |         'module_type', help="Type of module to find file for. [" + '|'.join(module_types) + "]") | ||||||
|  |     find_parser.add_argument('spec', nargs='+', help='spec to find a module file for.') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def dotkit_find(parser, args): | def module_find(mtype, spec_array): | ||||||
|     if not args.spec: |     specs = spack.cmd.parse_specs(spec_array) | ||||||
|         parser.parse_args(['dotkit', '-h']) |     if len(specs) > 1: | ||||||
| 
 |  | ||||||
|     spec = spack.cmd.parse_specs(args.spec) |  | ||||||
|     if len(spec) > 1: |  | ||||||
|         tty.die("You can only pass one spec.") |         tty.die("You can only pass one spec.") | ||||||
|     spec = spec[0] |     spec = specs[0] | ||||||
| 
 | 
 | ||||||
|     if not spack.db.exists(spec.name): |     if not spack.db.exists(spec.name): | ||||||
|         tty.die("No such package: %s" % spec.name) |         tty.die("No such package: %s" % spec.name) | ||||||
| 
 | 
 | ||||||
|     specs = [s for s in spack.db.installed_package_specs() if s.satisfies(spec)] |     if mtype not in module_types: | ||||||
|  |         tty.die("Invalid module type: '%s'.  Options are " + comma_and(module_types)) | ||||||
| 
 | 
 | ||||||
|  |     specs = [s for s in spack.db.installed_package_specs() if s.satisfies(spec)] | ||||||
|     if len(specs) == 0: |     if len(specs) == 0: | ||||||
|         tty.die("No installed packages match spec %s" % spec) |         tty.die("No installed packages match spec %s" % spec) | ||||||
| 
 | 
 | ||||||
| @@ -69,31 +78,27 @@ def dotkit_find(parser, args): | |||||||
|             sys.stderr.write(s.tree(color=True)) |             sys.stderr.write(s.tree(color=True)) | ||||||
|         sys.exit(1) |         sys.exit(1) | ||||||
| 
 | 
 | ||||||
|     match = specs[0] |     mt = module_types[mtype] | ||||||
|     if not os.path.isfile(spack.hooks.dotkit.dotkit_file(match.package)): |     mod = mt(spec.package) | ||||||
|  |     if not os.path.isfile(mod.file_name): | ||||||
|         tty.die("No dotkit is installed for package %s." % spec) |         tty.die("No dotkit is installed for package %s." % spec) | ||||||
| 
 | 
 | ||||||
|     print match.format('$_$@$+$%@$=$#') |     print mod.file_name | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def dotkit_refresh(parser, args): | def module_refresh(): | ||||||
|     query_specs = spack.cmd.parse_specs(args.spec) |     shutil.rmtree(spack.dotkit_path, ignore_errors=False) | ||||||
|  |     mkdirp(spack.dotkit_path) | ||||||
| 
 | 
 | ||||||
|     specs = spack.db.installed_package_specs() |     specs = spack.db.installed_package_specs() | ||||||
|     if query_specs: |  | ||||||
|         specs = [s for s in specs |  | ||||||
|                  if any(s.satisfies(q) for q in query_specs)] |  | ||||||
|     else: |  | ||||||
|         shutil.rmtree(spack.dotkit_path, ignore_errors=False) |  | ||||||
|         mkdirp(spack.dotkit_path) |  | ||||||
| 
 |  | ||||||
|     for spec in specs: |     for spec in specs: | ||||||
|         spack.hooks.dotkit.post_install(spec.package) |         for mt in module_types: | ||||||
|  |             mt(spec.package).write() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def module(parser, args): | ||||||
|  |     if args.module_command == 'refresh': | ||||||
|  |         module_refresh() | ||||||
| 
 | 
 | ||||||
| def dotkit(parser, args): |     elif args.module_command == 'find': | ||||||
|     if args.refresh: |         module_find(args.module_type, args.spec) | ||||||
|         dotkit_refresh(parser, args) |  | ||||||
|     else: |  | ||||||
|         dotkit_find(parser, args) |  | ||||||
| @@ -1,99 +0,0 @@ | |||||||
| ############################################################################## |  | ||||||
| # Copyright (c) 2013, Lawrence Livermore National Security, LLC. |  | ||||||
| # Produced at the Lawrence Livermore National Laboratory. |  | ||||||
| # |  | ||||||
| # This file is part of Spack. |  | ||||||
| # Written by David Beckingsale, david@llnl.gov, All rights reserved. |  | ||||||
| # LLNL-CODE-647188 |  | ||||||
| # |  | ||||||
| # For details, see https://scalability-llnl.github.io/spack |  | ||||||
| # Please also see the LICENSE file for our notice and the LGPL. |  | ||||||
| # |  | ||||||
| # This program is free software; you can redistribute it and/or modify |  | ||||||
| # it under the terms of the GNU General Public License (as published by |  | ||||||
| # the Free Software Foundation) version 2.1 dated February 1999. |  | ||||||
| # |  | ||||||
| # This program is distributed in the hope that it will be useful, but |  | ||||||
| # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF |  | ||||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and |  | ||||||
| # conditions of the GNU General Public License for more details. |  | ||||||
| # |  | ||||||
| # You should have received a copy of the GNU Lesser General Public License |  | ||||||
| # along with this program; if not, write to the Free Software Foundation, |  | ||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |  | ||||||
| ############################################################################## |  | ||||||
| import sys |  | ||||||
| import os |  | ||||||
| import shutil |  | ||||||
| import argparse |  | ||||||
|  |  | ||||||
| import llnl.util.tty as tty |  | ||||||
| from llnl.util.lang import partition_list |  | ||||||
| from llnl.util.filesystem import mkdirp |  | ||||||
|  |  | ||||||
| import spack.cmd |  | ||||||
| import spack.hooks.tclmodule |  | ||||||
| from spack.spec import Spec |  | ||||||
|  |  | ||||||
|  |  | ||||||
| description ="Find modules for packages if they exist." |  | ||||||
|  |  | ||||||
| def setup_parser(subparser): |  | ||||||
|     subparser.add_argument( |  | ||||||
|         '--refresh', action='store_true', help='Regenerate all modules') |  | ||||||
|  |  | ||||||
|     subparser.add_argument( |  | ||||||
|         'spec', nargs=argparse.REMAINDER, help='spec to find a module for.') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def module_find(parser, args): |  | ||||||
|     if not args.spec: |  | ||||||
|         parser.parse_args(['tclmodule', '-h']) |  | ||||||
|  |  | ||||||
|     spec = spack.cmd.parse_specs(args.spec) |  | ||||||
|     if len(spec) > 1: |  | ||||||
|         tty.die("You can only pass one spec.") |  | ||||||
|     spec = spec[0] |  | ||||||
|  |  | ||||||
|     if not spack.db.exists(spec.name): |  | ||||||
|         tty.die("No such package: %s" % spec.name) |  | ||||||
|  |  | ||||||
|     specs = [s for s in spack.db.installed_package_specs() if s.satisfies(spec)] |  | ||||||
|  |  | ||||||
|     if len(specs) == 0: |  | ||||||
|         tty.die("No installed packages match spec %s" % spec) |  | ||||||
|  |  | ||||||
|     if len(specs) > 1: |  | ||||||
|         tty.error("Multiple matches for spec %s.  Choose one:" % spec) |  | ||||||
|         for s in specs: |  | ||||||
|             sys.stderr.write(s.tree(color=True)) |  | ||||||
|         sys.exit(1) |  | ||||||
|  |  | ||||||
|     match = specs[0] |  | ||||||
|     if not os.path.isfile(spack.hooks.tclmodule.module_file(match.package)): |  | ||||||
|         tty.die("No module is installed for package %s." % spec) |  | ||||||
|  |  | ||||||
|     print match.format('$_$@$+$%@$=$#') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def module_refresh(parser, args): |  | ||||||
|     query_specs = spack.cmd.parse_specs(args.spec) |  | ||||||
|  |  | ||||||
|     specs = spack.db.installed_package_specs() |  | ||||||
|     if query_specs: |  | ||||||
|         specs = [s for s in specs |  | ||||||
|                  if any(s.satisfies(q) for q in query_specs)] |  | ||||||
|     else: |  | ||||||
|         shutil.rmtree(spack.tclmodule_path, ignore_errors=False) |  | ||||||
|         mkdirp(spack.tclmodule_path) |  | ||||||
|  |  | ||||||
|     for spec in specs: |  | ||||||
|         spack.hooks.tclmodule.post_install(spec.package) |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def tclmodule(parser, args): |  | ||||||
|     if args.refresh: |  | ||||||
|         module_refresh(parser, args) |  | ||||||
|     else: |  | ||||||
|         module_find(parser, args) |  | ||||||
| @@ -23,14 +23,16 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import argparse | import argparse | ||||||
| import spack.cmd.tclmodule | import spack.modules | ||||||
|  |  | ||||||
| description ="Remove package from environment using module." | description ="Remove package from environment using module." | ||||||
|  |  | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|  |     """Parser is only constructed so that this prints a nice help | ||||||
|  |        message with -h. """ | ||||||
|     subparser.add_argument( |     subparser.add_argument( | ||||||
|         'spec', nargs=argparse.REMAINDER, help='Spec of package to remove.') |         'spec', nargs=argparse.REMAINDER, help='Spec of package to unload with modules.') | ||||||
|  |  | ||||||
|  |  | ||||||
| def unload(parser, args): | def unload(parser, args): | ||||||
|     spack.cmd.load.print_help() |     spack.modules.print_help() | ||||||
|   | |||||||
| @@ -23,14 +23,16 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import argparse | import argparse | ||||||
| import spack.cmd.use | import spack.modules | ||||||
|  |  | ||||||
| description ="Remove package from environment using dotkit." | description ="Remove package from environment using dotkit." | ||||||
|  |  | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|  |     """Parser is only constructed so that this prints a nice help | ||||||
|  |        message with -h. """ | ||||||
|     subparser.add_argument( |     subparser.add_argument( | ||||||
|         'spec', nargs=argparse.REMAINDER, help='Spec of package to remove.') |         'spec', nargs=argparse.REMAINDER, help='Spec of package to unuse with dotkit.') | ||||||
|  |  | ||||||
|  |  | ||||||
| def unuse(parser, args): | def unuse(parser, args): | ||||||
|     spack.cmd.use.print_help() |     spack.modules.print_help() | ||||||
|   | |||||||
| @@ -23,28 +23,16 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import argparse | import argparse | ||||||
| import llnl.util.tty as tty | import spack.modules | ||||||
| import spack |  | ||||||
|  |  | ||||||
| description ="Add package to environment using dotkit." | description ="Add package to environment using dotkit." | ||||||
|  |  | ||||||
| def setup_parser(subparser): | def setup_parser(subparser): | ||||||
|  |     """Parser is only constructed so that this prints a nice help | ||||||
|  |        message with -h. """ | ||||||
|     subparser.add_argument( |     subparser.add_argument( | ||||||
|         'spec', nargs=argparse.REMAINDER, help='Spec of package to add.') |         'spec', nargs=argparse.REMAINDER, help='Spec of package to use with dotkit.') | ||||||
|  |  | ||||||
|  |  | ||||||
| def print_help(): |  | ||||||
|     tty.msg("Spack dotkit support is not initialized.", |  | ||||||
|             "", |  | ||||||
|             "To use dotkit with Spack, you must first run the command", |  | ||||||
|             "below, which you can copy and paste:", |  | ||||||
|             "", |  | ||||||
|             "For bash:", |  | ||||||
|             "    . %s/setup-env.bash" % spack.share_path, |  | ||||||
|             "", |  | ||||||
|             "ksh/csh/tcsh shells are currently unsupported", |  | ||||||
|             "") |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def use(parser, args): | def use(parser, args): | ||||||
|     print_help() |     spack.modules.print_help() | ||||||
|   | |||||||
| @@ -22,62 +22,14 @@ | |||||||
| # along with this program; if not, write to the Free Software Foundation, | # along with this program; if not, write to the Free Software Foundation, | ||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import os | import spack.modules | ||||||
| import re |  | ||||||
| import textwrap |  | ||||||
| import shutil |  | ||||||
| from contextlib import closing |  | ||||||
|  |  | ||||||
| from llnl.util.filesystem import join_path, mkdirp |  | ||||||
|  |  | ||||||
| import spack |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def dotkit_file(pkg): |  | ||||||
|     dk_file_name = pkg.spec.format('$_$@$%@$+$=$#') + ".dk" |  | ||||||
|     return join_path(spack.dotkit_path, dk_file_name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def post_install(pkg): | def post_install(pkg): | ||||||
|     if not os.path.exists(spack.dotkit_path): |     dk = spack.modules.Dotkit(pkg) | ||||||
|         mkdirp(spack.dotkit_path) |     dk.write() | ||||||
|  |  | ||||||
|     alterations = [] |  | ||||||
|     for var, path in [ |  | ||||||
|         ('PATH', pkg.prefix.bin), |  | ||||||
|         ('MANPATH', pkg.prefix.man), |  | ||||||
|         ('MANPATH', pkg.prefix.share_man), |  | ||||||
|         ('LD_LIBRARY_PATH', pkg.prefix.lib), |  | ||||||
|         ('LD_LIBRARY_PATH', pkg.prefix.lib64)]: |  | ||||||
|  |  | ||||||
|         if os.path.isdir(path): |  | ||||||
|             alterations.append("dk_alter %s %s\n" % (var, path)) |  | ||||||
|  |  | ||||||
|     if not alterations: |  | ||||||
|         return |  | ||||||
|  |  | ||||||
|     alterations.append("dk_alter CMAKE_PREFIX_PATH %s\n" % pkg.prefix) |  | ||||||
|  |  | ||||||
|     dk_file = dotkit_file(pkg) |  | ||||||
|     with closing(open(dk_file, 'w')) as dk: |  | ||||||
|         # Put everything in the spack category. |  | ||||||
|         dk.write('#c spack\n') |  | ||||||
|  |  | ||||||
|         dk.write('#d %s\n' % pkg.spec.format("$_ $@")) |  | ||||||
|  |  | ||||||
|         # Recycle the description |  | ||||||
|         if pkg.__doc__: |  | ||||||
|             doc = re.sub(r'\s+', ' ', pkg.__doc__) |  | ||||||
|             for line in textwrap.wrap(doc, 72): |  | ||||||
|                 dk.write("#h %s\n" % line) |  | ||||||
|  |  | ||||||
|         # Write alterations |  | ||||||
|         for alter in alterations: |  | ||||||
|             dk.write(alter) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def post_uninstall(pkg): | def post_uninstall(pkg): | ||||||
|     dk_file = dotkit_file(pkg) |     dk = spack.modules.Dotkit(pkg) | ||||||
|     if os.path.exists(dk_file): |     dk.remove() | ||||||
|         shutil.rmtree(dk_file, ignore_errors=True) |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,65 +22,14 @@ | |||||||
| # along with this program; if not, write to the Free Software Foundation, | # along with this program; if not, write to the Free Software Foundation, | ||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import os | import spack.modules | ||||||
| import re |  | ||||||
| import textwrap |  | ||||||
| import shutil |  | ||||||
| from contextlib import closing |  | ||||||
|  |  | ||||||
| from llnl.util.filesystem import join_path, mkdirp |  | ||||||
|  |  | ||||||
| import spack |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def module_file(pkg): |  | ||||||
|     m_file_name = pkg.spec.format('$_$@$%@$+$=$#') |  | ||||||
|     return join_path(spack.tclmodule_path, m_file_name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def post_install(pkg): | def post_install(pkg): | ||||||
|     if not os.path.exists(spack.module_path): |     dk = spack.modules.TclModule(pkg) | ||||||
|         mkdirp(spack.module_path) |     dk.write() | ||||||
|  |  | ||||||
|     alterations = [] |  | ||||||
|     for var, path in [ |  | ||||||
|         ('PATH', pkg.prefix.bin), |  | ||||||
|         ('MANPATH', pkg.prefix.man), |  | ||||||
|         ('MANPATH', pkg.prefix.share_man), |  | ||||||
|         ('LD_LIBRARY_PATH', pkg.prefix.lib), |  | ||||||
|         ('LD_LIBRARY_PATH', pkg.prefix.lib64)]: |  | ||||||
|  |  | ||||||
|         if os.path.isdir(path): |  | ||||||
|             alterations.append("prepend-path %s \"%s\"\n" % (var, path)) |  | ||||||
|  |  | ||||||
|     if not alterations: |  | ||||||
|         return |  | ||||||
|  |  | ||||||
|     alterations.append("prepend-path CMAKE_PREFIX_PATH \"%s\"\n" % pkg.prefix) |  | ||||||
|  |  | ||||||
|     m_file = module_file(pkg) |  | ||||||
|     with closing(open(m_file, 'w')) as m: |  | ||||||
|         # Put everything in the spack category. |  | ||||||
|         m.write('#%Module1.0\n') |  | ||||||
|  |  | ||||||
|         m.write('module-whatis \"%s\"\n\n' % pkg.spec.format("$_ $@")) |  | ||||||
|  |  | ||||||
|         # Recycle the description |  | ||||||
|         if pkg.__doc__: |  | ||||||
|             m.write('proc ModulesHelp { } {\n') |  | ||||||
|             doc = re.sub(r'\s+', ' ', pkg.__doc__) |  | ||||||
|             doc = re.sub(r'"', '\"', pkg.__doc__) |  | ||||||
|             m.write("puts stderr \"%s\"\n" % doc) |  | ||||||
|             m.write('}\n\n') |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         # Write alterations |  | ||||||
|         for alter in alterations: |  | ||||||
|             m.write(alter) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def post_uninstall(pkg): | def post_uninstall(pkg): | ||||||
|     m_file = module_file(pkg) |     dk = spack.modules.TclModule(pkg) | ||||||
|     if os.path.exists(m_file): |     dk.remove() | ||||||
|         shutil.rmtree(m_file, ignore_errors=True) |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										216
									
								
								lib/spack/spack/modules.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								lib/spack/spack/modules.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | |||||||
|  | ############################################################################## | ||||||
|  | # Copyright (c) 2013, Lawrence Livermore National Security, LLC. | ||||||
|  | # Produced at the Lawrence Livermore National Laboratory. | ||||||
|  | # | ||||||
|  | # This file is part of Spack. | ||||||
|  | # Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. | ||||||
|  | # LLNL-CODE-647188 | ||||||
|  | # | ||||||
|  | # For details, see https://scalability-llnl.github.io/spack | ||||||
|  | # Please also see the LICENSE file for our notice and the LGPL. | ||||||
|  | # | ||||||
|  | # This program is free software; you can redistribute it and/or modify | ||||||
|  | # it under the terms of the GNU General Public License (as published by | ||||||
|  | # the Free Software Foundation) version 2.1 dated February 1999. | ||||||
|  | # | ||||||
|  | # This program is distributed in the hope that it will be useful, but | ||||||
|  | # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF | ||||||
|  | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and | ||||||
|  | # conditions of the GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | # You should have received a copy of the GNU Lesser General Public License | ||||||
|  | # along with this program; if not, write to the Free Software Foundation, | ||||||
|  | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
|  | ############################################################################## | ||||||
|  | """This module contains code for creating environment modules, which | ||||||
|  | can include dotkits, tcl modules, lmod, and others. | ||||||
|  |  | ||||||
|  | The various types of modules are installed by post-install hooks and | ||||||
|  | removed after an uninstall by post-uninstall hooks.  This class | ||||||
|  | consolidates the logic for creating an abstract description of the | ||||||
|  | information that module systems need.  Currently that includes a | ||||||
|  | number directories to be appended to paths in the user's environment: | ||||||
|  |  | ||||||
|  |   * /bin directories to be appended to PATH | ||||||
|  |   * /lib* directories for LD_LIBRARY_PATH | ||||||
|  |   * /man* and /share/man* directories for LD_LIBRARY_PATH | ||||||
|  |   * the package prefix for CMAKE_PREFIX_PATH | ||||||
|  |  | ||||||
|  | This module also includes logic for coming up with unique names for | ||||||
|  | the module files so that they can be found by the various | ||||||
|  | shell-support files in $SPACK/share/spack/setup-env.*. | ||||||
|  |  | ||||||
|  | Each hook in hooks/ implements the logic for writing its specific type | ||||||
|  | of module file. | ||||||
|  | """ | ||||||
|  | __all__ = ['EnvModule', 'Dotkit', 'TclModule'] | ||||||
|  |  | ||||||
|  | import os | ||||||
|  | import re | ||||||
|  | import textwrap | ||||||
|  | import shutil | ||||||
|  | from contextlib import closing | ||||||
|  |  | ||||||
|  | import llnl.util.tty as tty | ||||||
|  | from llnl.util.filesystem import join_path, mkdirp | ||||||
|  |  | ||||||
|  | import spack | ||||||
|  |  | ||||||
|  | dotkit_path  = join_path(spack.share_path, "dotkit") | ||||||
|  | tcl_mod_path = join_path(spack.share_path, "modules") | ||||||
|  |  | ||||||
|  | def print_help(): | ||||||
|  |     """For use by commands to tell user how to activate shell support.""" | ||||||
|  |  | ||||||
|  |     tty.msg("Spack module/dotkit support is not initialized.", | ||||||
|  |             "", | ||||||
|  |             "To use dotkit or modules with Spack, you must first run", | ||||||
|  |             "one of the commands below.  You can copy/paste them.", | ||||||
|  |             "", | ||||||
|  |             "For bash and zsh:", | ||||||
|  |             "    . %s/setup-env.sh" % spack.share_path, | ||||||
|  |             "", | ||||||
|  |             "For csh and tcsh:", | ||||||
|  |             "    source %s/setup-env.csh" % spack.share_path, | ||||||
|  |             "") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class EnvModule(object): | ||||||
|  |     def __init__(self, pkg=None): | ||||||
|  |         # category in the modules system | ||||||
|  |         # TODO: come up with smarter category names. | ||||||
|  |         self.category = "spack" | ||||||
|  |  | ||||||
|  |         # Descriptions for the module system's UI | ||||||
|  |         self.short_description = "" | ||||||
|  |         self.long_description = "" | ||||||
|  |  | ||||||
|  |         # dict pathname -> list of directories to be prepended to in | ||||||
|  |         # the module file. | ||||||
|  |         self._paths = None | ||||||
|  |         self.pkg = pkg | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def paths(self): | ||||||
|  |         if self._paths is None: | ||||||
|  |             self._paths = {} | ||||||
|  |  | ||||||
|  |             def add_path(self, path_name, directory): | ||||||
|  |                 path = self._paths.setdefault(path_name, []) | ||||||
|  |                 path.append(directory) | ||||||
|  |  | ||||||
|  |             # Add paths if they exist. | ||||||
|  |             for var, directory in [ | ||||||
|  |                     ('PATH', self.pkg.prefix.bin), | ||||||
|  |                     ('MANPATH', self.pkg.prefix.man), | ||||||
|  |                     ('MANPATH', self.pkg.prefix.share_man), | ||||||
|  |                     ('LD_LIBRARY_PATH', self.pkg.prefix.lib), | ||||||
|  |                     ('LD_LIBRARY_PATH', self.pkg.prefix.lib64)]: | ||||||
|  |  | ||||||
|  |                 if os.path.isdir(directory): | ||||||
|  |                     add_path(var, directory) | ||||||
|  |  | ||||||
|  |             # short description is just the package + version | ||||||
|  |             # TODO: maybe packages can optionally provide it. | ||||||
|  |             self.short_description = self.pkg.spec.format("$_ $@") | ||||||
|  |  | ||||||
|  |             # long description is the docstring with reduced whitespace. | ||||||
|  |             if self.pkg.__doc__: | ||||||
|  |                 self.long_description = re.sub(r'\s+', ' ', self.pkg.__doc__) | ||||||
|  |  | ||||||
|  |         return self._paths | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def write(self): | ||||||
|  |         """Write out a module file for this object.""" | ||||||
|  |         module_dir = os.path.dirname(self.file_name) | ||||||
|  |         if not os.path.exists(): | ||||||
|  |             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: | ||||||
|  |             self._write(f) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def _write(self, stream): | ||||||
|  |         """To be implemented by subclasses.""" | ||||||
|  |         raise NotImplementedError() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def file_name(self): | ||||||
|  |         """Subclasses should implement this to return the name of the file | ||||||
|  |            where this module lives.""" | ||||||
|  |         return self.pkg.spec.format('$_$@$%@$+$=$#') | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def remove(self): | ||||||
|  |         mod_file = self.file_name | ||||||
|  |         if os.path.exists(mod_file): | ||||||
|  |             shutil.rmtree(mod_file, ignore_errors=True) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Dotkit(EnvModule): | ||||||
|  |     @property | ||||||
|  |     def file_name(self): | ||||||
|  |         spec = self.pkg.spec | ||||||
|  |         return join_path(dotkit_path, spec.architecture, | ||||||
|  |                          spec.format('$_$@$%@$+$#.dk')) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def _write(self, dk_file): | ||||||
|  |         # Category | ||||||
|  |         if self.category: | ||||||
|  |             dk_file.write('#c %s\n' % self.category) | ||||||
|  |  | ||||||
|  |         # Short description | ||||||
|  |         if self.short_description: | ||||||
|  |             dk_file.write('#d %s\n' % self.short_description) | ||||||
|  |  | ||||||
|  |         # Long description | ||||||
|  |         if self.long_description: | ||||||
|  |             for line in textwrap.wrap(self.long_description, 72): | ||||||
|  |                 dk_file.write("#h %s\n" % line) | ||||||
|  |  | ||||||
|  |         # Path alterations | ||||||
|  |         for var, dirs in self.paths.items(): | ||||||
|  |             for directory in dirs: | ||||||
|  |                 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) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TclModule(EnvModule): | ||||||
|  |     @property | ||||||
|  |     def file_name(self): | ||||||
|  |         spec = self.pkg.spec | ||||||
|  |         return join_path(tcl_mod_path, spec.architecture, | ||||||
|  |                          spec.format('$_$@$%@$+$#')) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     def _write(self, m_file): | ||||||
|  |         # TODO: cateogry? | ||||||
|  |         m_file.write('#%Module1.0\n') | ||||||
|  |  | ||||||
|  |         # Short description | ||||||
|  |         if self.short_description: | ||||||
|  |             m_file.write('module-whatis \"%s\"\n\n' % self.short_description) | ||||||
|  |  | ||||||
|  |         # Long description | ||||||
|  |         if self.long_description: | ||||||
|  |             m_file.write('proc ModulesHelp { } {\n') | ||||||
|  |             doc = re.sub(r'"', '\"', self.long_description) | ||||||
|  |             m_file.write("puts stderr \"%s\"\n" % doc) | ||||||
|  |             m_file.write('}\n\n') | ||||||
|  |  | ||||||
|  |         # Path alterations | ||||||
|  |         for var, dirs in self.paths.items(): | ||||||
|  |             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) | ||||||
| @@ -23,16 +23,13 @@ | |||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| 
 | 
 | ||||||
| # |  | ||||||
| # | # | ||||||
| # This file is part of Spack and sets up the spack environment for | # This file is part of Spack and sets up the spack environment for | ||||||
| # bash shells.  This includes dotkit support as well as putting spack | # bash and zsh.  This includes dotkit support, module support, and | ||||||
| # in your path.  Source it like this: | # it also puts spack in your path.  Source it like this: | ||||||
| # | # | ||||||
| #    . /path/to/spack/share/spack/setup-env.bash | #    . /path/to/spack/share/spack/setup-env.sh | ||||||
| # | # | ||||||
| # |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| ######################################################################## | ######################################################################## | ||||||
| # This is a wrapper around the spack command that forwards calls to | # This is a wrapper around the spack command that forwards calls to | ||||||
| @@ -59,56 +56,46 @@ | |||||||
| # spack dotfiles. | # spack dotfiles. | ||||||
| ######################################################################## | ######################################################################## | ||||||
| function spack { | function spack { | ||||||
|     _spack_subcommand=$1; shift |     _sp_subcommand=$1; shift | ||||||
|     _spack_spec="$@" |     _sp_spec="$@" | ||||||
| 
 | 
 | ||||||
|     # Filter out use and unuse.  For any other commands, just run the |     # Filter out use and unuse.  For any other commands, just run the | ||||||
|     # command. |     # command. | ||||||
|     case $_spack_subcommand in |     case $_sp_subcommand in | ||||||
|         "use"|"unuse") |         "use"|"unuse"|"load"|"unload") | ||||||
|             # Shift any other args for use off before parsing spec. |             # Shift any other args for use off before parsing spec. | ||||||
|             _spack_use_args="" |             _sp_module_args="" | ||||||
|             if [[ "$1" =~ ^- ]]; then |             if [[ "$1" =~ ^- ]]; then | ||||||
|                 _spack_use_args="$1"; shift |                 _sp_module_args="$1"; shift | ||||||
|                 _spack_spec="$@" |                 _sp_spec="$@" | ||||||
|             fi |             fi | ||||||
| 
 | 
 | ||||||
|             # Here the user has run use or unuse with a spec.  Find a matching |             # Translate the parameter into pieces of a command. | ||||||
|             # spec with a dotkit using spack dotkit, then use or unuse the |             # _sp_modtype is an arg to spack module find, and | ||||||
|             # result.  If spack dotkit comes back with an error, do nothing. |             # _sp_sh_cmd is the equivalent shell command. | ||||||
|             if _spack_full_spec=$(command spack dotkit $_spack_spec); then |             case $_sp_subcommand in | ||||||
|                 $_spack_subcommand $_spack_use_args $_spack_full_spec |                 "use"|"unuse") | ||||||
|             fi |                     _sp_modtype=dotkit | ||||||
|             return |                     _sp_sh_cmd=$_sp_subcommand | ||||||
|             ;; |                     ;; | ||||||
|         "load"|"unload") |                 "load"|"unload") | ||||||
|             # Shift any other args for module off before parsing spec. |                     _sp_modtype=tcl | ||||||
|             _spack_module_args="" |                     _sp_sh_cmd="module $_sp_subcommand" | ||||||
|             if [[ "$1" =~ ^- ]]; then |                     ;; | ||||||
|                 _spack_module_args="$1"; shift |             esac | ||||||
|                 _spack_spec="$@" |  | ||||||
|             fi |  | ||||||
| 
 | 
 | ||||||
|             # Here the user has run use or unuse with a spec.  Find a matching |             # Here the user has run use or unuse with a spec.  Find a matching | ||||||
|             # spec with a dotkit using spack dotkit, then use or unuse the |             # spec using 'spack module find', then use the appropriate module | ||||||
|             # result.  If spack dotkit comes back with an error, do nothing. |             # tool's commands to add/remove the result from the environment. | ||||||
|             if _spack_full_spec=$(command spack tclmodule $_spack_spec); then |             # If spack module command comes back with an error, do nothing. | ||||||
|                 $_spack_subcommand $_spack_module_args $_spack_full_spec |             if _sp_full_spec=$(command spack module find $_sp_modtype $_sp_spec); then | ||||||
|  |                 $_sp_sh_cmd $_sp_module_args $_sp_full_spec | ||||||
|             fi |             fi | ||||||
|             return |             return | ||||||
|             ;; |             ;; | ||||||
|         *) |         *) | ||||||
|             command spack $_spack_subcommand "$@" |             command spack $_sp_subcommand $_sp_spec | ||||||
|             return |  | ||||||
|             ;; |  | ||||||
|     esac |     esac | ||||||
| 
 |  | ||||||
|     # If no args or -h, just run that command as well. |  | ||||||
|     if [ -z "$1" -o "$1" = "-h" ]; then |  | ||||||
|         command spack $_spack_subcommand -h |  | ||||||
|         return |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ######################################################################## | ######################################################################## | ||||||
| @@ -119,31 +106,45 @@ function spack { | |||||||
| function _spack_pathadd { | function _spack_pathadd { | ||||||
|     # If no variable name is supplied, just append to PATH |     # If no variable name is supplied, just append to PATH | ||||||
|     # otherwise append to that variable. |     # otherwise append to that variable. | ||||||
|     varname=PATH |     _pa_varname=PATH | ||||||
|     path="$1" |     _pa_new_path="$1" | ||||||
|     if [ -n "$2" ]; then |     if [ -n "$2" ]; then | ||||||
|         varname="$1" |         _pa_varname="$1" | ||||||
|         path="$2" |         _pa_new_path="$2" | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     # Do the actual prepending here. |     # Do the actual prepending here. | ||||||
|     eval "oldvalue=\"\$$varname\"" |     eval "_pa_oldvalue=\$${_pa_varname}" | ||||||
|     if [ -d "$path" ] && [[ ":$oldvalue:" != *":$path:"* ]]; then | 
 | ||||||
|         if [ -n "$oldvalue" ]; then |     if [ -d "$_pa_new_path" ] && [[ ":$_pa_oldvalue:" != *":$_pa_new_path:"* ]]; then | ||||||
|             eval "export $varname=\"$path:$oldvalue\"" |         if [ -n "$_pa_oldvalue" ]; then | ||||||
|  |             eval "export $_pa_varname=\"$_pa_new_path:$_pa_oldvalue\"" | ||||||
|         else |         else | ||||||
|             export $varname="$path" |             export $_pa_varname="$_pa_new_path" | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | # | ||||||
|  | # Figure out where this file is.  Below code needs to be portable to | ||||||
|  | # bash and zsh. | ||||||
|  | # | ||||||
|  | _sp_source_file="${BASH_SOURCE[0]}"  # Bash's location of last sourced file. | ||||||
|  | if [ -z "$_sp_source_file" ]; then | ||||||
|  |     _sp_source_file="$0:A"           # zsh way to do it | ||||||
|  |     if [[ "$_sp_source_file" == *":A" ]]; then | ||||||
|  |         # Not zsh either... bail out with plain old $0, | ||||||
|  |         # which WILL NOT work if this is sourced indirectly. | ||||||
|  |         _sp_source_file="$0" | ||||||
|  |     fi | ||||||
|  | fi | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
| # Set up dotkit and path in the user environment | # Set up modules and dotkit search paths in the user environment | ||||||
| # | # | ||||||
| _spack_share_dir="$(dirname ${BASH_SOURCE[0]})" | _sp_share_dir="$(dirname $_sp_source_file)" | ||||||
| _spack_prefix="$(dirname $(dirname $_spack_share_dir))" | _sp_prefix="$(dirname $(dirname $_sp_share_dir))" | ||||||
| 
 | 
 | ||||||
| _spack_pathadd DK_NODE "$_spack_share_dir/dotkit" | _spack_pathadd DK_NODE    "$_sp_share_dir/dotkit" | ||||||
| _spack_pathadd MODULEPATH "$_spack_share_dir/modules" | _spack_pathadd MODULEPATH "$_sp_share_dir/modules" | ||||||
| _spack_pathadd PATH    "$_spack_prefix/bin" | _spack_pathadd PATH       "$_sp_prefix/bin" | ||||||
| @@ -1,122 +0,0 @@ | |||||||
| ############################################################################## |  | ||||||
| # Copyright (c) 2013, Lawrence Livermore National Security, LLC. |  | ||||||
| # Produced at the Lawrence Livermore National Laboratory. |  | ||||||
| # |  | ||||||
| # This file is part of Spack. |  | ||||||
| # Written by David Beckingsale, david@llnl.gov, All rights reserved. |  | ||||||
| # LLNL-CODE-647188 |  | ||||||
| # |  | ||||||
| # For details, see https://scalability-llnl.github.io/spack |  | ||||||
| # Please also see the LICENSE file for our notice and the LGPL. |  | ||||||
| # |  | ||||||
| # This program is free software; you can redistribute it and/or modify |  | ||||||
| # it under the terms of the GNU General Public License (as published by |  | ||||||
| # the Free Software Foundation) version 2.1 dated February 1999. |  | ||||||
| # |  | ||||||
| # This program is distributed in the hope that it will be useful, but |  | ||||||
| # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF |  | ||||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and |  | ||||||
| # conditions of the GNU General Public License for more details. |  | ||||||
| # |  | ||||||
| # You should have received a copy of the GNU Lesser General Public License |  | ||||||
| # along with this program; if not, write to the Free Software Foundation, |  | ||||||
| # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |  | ||||||
| ############################################################################## |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # |  | ||||||
| # This file is part of Spack and sets up the spack environment for zsh shells. |  | ||||||
| # This includes dotkit and module support as well as putting spack |  | ||||||
| # in your path.  Source it like this: |  | ||||||
| # |  | ||||||
| #    source /path/to/spack/share/spack/setup-env.zsh |  | ||||||
| # |  | ||||||
| # |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ######################################################################## |  | ||||||
| # This is a wrapper around the spack command that forwards calls to |  | ||||||
| # 'spack use' and 'spack unuse' to shell functions.  This in turn |  | ||||||
| # allows them to be used to invoke dotkit functions. |  | ||||||
| # |  | ||||||
| # 'spack use' is smarter than just 'use' because it converts its |  | ||||||
| # arguments into a unique spack spec that is then passed to dotkit |  | ||||||
| # commands.  This allows the user to use packages without knowing all |  | ||||||
| # their installation details. |  | ||||||
| # |  | ||||||
| # e.g., rather than requring a full spec for libelf, the user can type: |  | ||||||
| # |  | ||||||
| #     spack use libelf |  | ||||||
| # |  | ||||||
| # This will first find the available libelf dotkits and use a |  | ||||||
| # matching one.  If there are two versions of libelf, the user would |  | ||||||
| # need to be more specific, e.g.: |  | ||||||
| # |  | ||||||
| #     spack use libelf@0.8.13 |  | ||||||
| # |  | ||||||
| # This is very similar to how regular spack commands work and it |  | ||||||
| # avoids the need to come up with a user-friendly naming scheme for |  | ||||||
| # spack dotfiles. |  | ||||||
| ######################################################################## |  | ||||||
| function spack { |  | ||||||
|     _spack_subcommand=${1}; shift |  | ||||||
|     _spack_spec="$@" |  | ||||||
|  |  | ||||||
|     # Filter out use and unuse.  For any other commands, just run the |  | ||||||
|     # command. |  | ||||||
|     case ${_spack_subcommand} in |  | ||||||
|         "use"|"unuse") |  | ||||||
|             # Shift any other args for use off before parsing spec. |  | ||||||
|             _spack_use_args="" |  | ||||||
|             if [[ "$1" =~ ^- ]]; then |  | ||||||
|                 _spack_use_args="$1"; shift |  | ||||||
|                 _spack_spec="$@" |  | ||||||
|             fi |  | ||||||
|  |  | ||||||
|             # Here the user has run use or unuse with a spec.  Find a matching |  | ||||||
|             # spec with a dotkit using spack dotkit, then use or unuse the |  | ||||||
|             # result.  If spack dotkit comes back with an error, do nothing. |  | ||||||
|             if _spack_full_spec=$(command spack dotkit $_spack_spec); then |  | ||||||
|                 $_spack_subcommand $_spack_use_args $_spack_full_spec |  | ||||||
|             fi |  | ||||||
|             return |  | ||||||
|             ;; |  | ||||||
|         "load"|"unload") |  | ||||||
|             # Shift any other args for module off before parsing spec. |  | ||||||
|             _spack_module_args="" |  | ||||||
|             if [[ "$1" =~ ^- ]]; then |  | ||||||
|                 _spack_module_args="$1"; shift |  | ||||||
|                 _spack_spec="$@" |  | ||||||
|             fi |  | ||||||
|  |  | ||||||
|             # Here the user has run use or unuse with a spec.  Find a matching |  | ||||||
|             # spec with a dotkit using spack dotkit, then use or unuse the |  | ||||||
|             # result.  If spack dotkit comes back with an error, do nothing. |  | ||||||
|             if _spack_full_spec=$(command spack tclmodule ${_spack_spec}); then |  | ||||||
|                 module ${_spack_subcommand} ${_spack_module_args} ${_spack_full_spec} |  | ||||||
|             fi |  | ||||||
|             return |  | ||||||
|             ;; |  | ||||||
|         *) |  | ||||||
|             command spack $_spack_subcommand "$@" |  | ||||||
|             return |  | ||||||
|             ;; |  | ||||||
|     esac |  | ||||||
|  |  | ||||||
|     # If no args or -h, just run that command as well. |  | ||||||
|     if [ -z "$1" -o "$1" = "-h" ]; then |  | ||||||
|         command spack $_spack_subcommand -h |  | ||||||
|         return |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # |  | ||||||
| # Set up dotkit and path in the user environment |  | ||||||
| # |  | ||||||
| _spack_share_dir="$(dirname $0:A)" |  | ||||||
| _spack_prefix="$(dirname $(dirname ${_spack_share_dir}))" |  | ||||||
|  |  | ||||||
| export DK_NODE="$_spack_share_dir/dotkit:$DK_NODE" |  | ||||||
| export MODULEPATH="$_spack_share_dir/modules:$MODULEPATH" |  | ||||||
| export PATH="$_spack_prefix/bin:$PATH" |  | ||||||
		Reference in New Issue
	
	Block a user
	 Todd Gamblin
					Todd Gamblin