From 94c5c9667c786e05a635787e803d2cf7e22de73a Mon Sep 17 00:00:00 2001 From: David Beckingsale Date: Thu, 31 Jul 2014 13:42:34 -0700 Subject: Added inital module support --- lib/spack/spack/__init__.py | 1 + lib/spack/spack/cmd/load.py | 50 +++++++++++++++++++ lib/spack/spack/cmd/tclmodule.py | 99 ++++++++++++++++++++++++++++++++++++++ lib/spack/spack/cmd/unload.py | 36 ++++++++++++++ lib/spack/spack/hooks/tclmodule.py | 85 ++++++++++++++++++++++++++++++++ 5 files changed, 271 insertions(+) create mode 100644 lib/spack/spack/cmd/load.py create mode 100644 lib/spack/spack/cmd/tclmodule.py create mode 100644 lib/spack/spack/cmd/unload.py create mode 100644 lib/spack/spack/hooks/tclmodule.py (limited to 'lib') diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py index 50fe453cfb..bc24766510 100644 --- a/lib/spack/spack/__init__.py +++ b/lib/spack/spack/__init__.py @@ -59,6 +59,7 @@ stage_path = join_path(var_path, "stage") install_path = join_path(prefix, "opt") share_path = join_path(prefix, "share", "spack") dotkit_path = join_path(share_path, "dotkit") +tclmodule_path = join_path(share_path, "tclmodule") # # Set up the packages database. diff --git a/lib/spack/spack/cmd/load.py b/lib/spack/spack/cmd/load.py new file mode 100644 index 0000000000..1389740df1 --- /dev/null +++ b/lib/spack/spack/cmd/load.py @@ -0,0 +1,50 @@ +############################################################################## +# 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 argparse +import llnl.util.tty as tty +import spack + +description ="Add package to environment using module." + +def setup_parser(subparser): + subparser.add_argument( + 'spec', nargs=argparse.REMAINDER, help='Spec of package to add.') + + +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): + print_help() diff --git a/lib/spack/spack/cmd/tclmodule.py b/lib/spack/spack/cmd/tclmodule.py new file mode 100644 index 0000000000..da5c4f95fc --- /dev/null +++ b/lib/spack/spack/cmd/tclmodule.py @@ -0,0 +1,99 @@ +############################################################################## +# 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.tclmodules.tclmodules_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.module_path, ignore_errors=False) + mkdirp(spack.module_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) diff --git a/lib/spack/spack/cmd/unload.py b/lib/spack/spack/cmd/unload.py new file mode 100644 index 0000000000..df009c840b --- /dev/null +++ b/lib/spack/spack/cmd/unload.py @@ -0,0 +1,36 @@ +############################################################################## +# 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 argparse +import spack.cmd.tclmodule + +description ="Remove package from environment using module." + +def setup_parser(subparser): + subparser.add_argument( + 'spec', nargs=argparse.REMAINDER, help='Spec of package to remove.') + + +def unload(parser, args): + spack.cmd.load.print_help() diff --git a/lib/spack/spack/hooks/tclmodule.py b/lib/spack/spack/hooks/tclmodule.py new file mode 100644 index 0000000000..7df41e267c --- /dev/null +++ b/lib/spack/spack/hooks/tclmodule.py @@ -0,0 +1,85 @@ +############################################################################## +# 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 os +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.module_path, m_file_name) + + +def post_install(pkg): + if not os.path.exists(spack.module_path): + mkdirp(spack.module_path) + + 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' % pkg.spec.format("$_ $@")) + + # Recycle the description + if pkg.__doc__: + m.write('proc ModulesHelp { } {\n') + doc = re.sub(r'\s+', ' ', pkg.__doc__) + m.write("puts str \"%s\"\n" % doc) + m.write('}') + + + # Write alterations + for alter in alterations: + m.write(alter) + + +def post_uninstall(pkg): + m_file = module_file(pkg) + if os.path.exists(m_file): + shutil.rmtree(m_file, ignore_errors=True) + -- cgit v1.2.3-70-g09d2