diff options
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/sbang | 19 | ||||
-rwxr-xr-x | bin/spack | 110 |
2 files changed, 90 insertions, 39 deletions
@@ -79,6 +79,15 @@ # Obviously, for this to work, `sbang` needs to have a short enough # path that *it* will run without hitting OS limits. # +# For Lua, scripts the second line can't start with #!, as # is not +# the comment character in lua (even though lua ignores #! on the +# *first* line of a script). So, instrument a lua script like this, +# using -- instead of # on the second line: +# +# 1 #!/bin/bash /path/to/sbang +# 2 --!/long/path/to/lua with arguments +# 3 +# 4 print "success!" # # How it works # ----------------------------- @@ -95,13 +104,19 @@ lines=0 while read line && ((lines < 2)) ; do if [[ "$line" = '#!'* ]]; then interpreter="${line#\#!}" + elif [[ "$line" = '--!'*lua* ]]; then + interpreter="${line#--!}" fi lines=$((lines+1)) done < "$script" # Invoke any interpreter found, or raise an error if none was found. -if [ -n "$interpreter" ]; then - exec $interpreter "$@" +if [[ -n "$interpreter" ]]; then + if [[ "${interpreter##*/}" = "perl" ]]; then + exec $interpreter -x "$@" + else + exec $interpreter "$@" + fi else echo "error: sbang found no interpreter in $script" exit 1 @@ -1,4 +1,5 @@ #!/usr/bin/env python +# flake8: noqa ############################################################################## # Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. # Produced at the Lawrence Livermore National Laboratory. @@ -24,11 +25,13 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## import sys -if not sys.version_info[:2] >= (2,6): +if (sys.version_info[0] > 2) or (sys.version_info[:2] < (2, 6)): v_info = sys.version_info[:3] - sys.exit("Spack requires Python 2.6 or higher. This is Python %d.%d.%d." % v_info) + sys.exit("Spack requires Python 2.6 or 2.7. " + "This is Python %d.%d.%d." % v_info) import os +import inspect # Find spack's location and its prefix. SPACK_FILE = os.path.realpath(os.path.expanduser(__file__)) @@ -38,31 +41,34 @@ SPACK_PREFIX = os.path.dirname(os.path.dirname(SPACK_FILE)) # Allow spack libs to be imported in our scripts SPACK_LIB_PATH = os.path.join(SPACK_PREFIX, "lib", "spack") sys.path.insert(0, SPACK_LIB_PATH) + +# Add external libs SPACK_EXTERNAL_LIBS = os.path.join(SPACK_LIB_PATH, "external") sys.path.insert(0, SPACK_EXTERNAL_LIBS) -import warnings -# Avoid warnings when nose is installed with the python exe being used to run -# spack. Note this must be done after Spack's external libs directory is added -# to sys.path. -with warnings.catch_warnings(): - warnings.filterwarnings("ignore", ".*nose was already imported") - import nose - # Quick and dirty check to clean orphaned .pyc files left over from # previous revisions. These files were present in earlier versions of # Spack, were removed, but shadow system modules that Spack still # imports. If we leave them, Spack will fail in mysterious ways. # TODO: more elegant solution for orphaned pyc files. -orphaned_pyc_files = [os.path.join(SPACK_EXTERNAL_LIBS, n) - for n in ('functools.pyc', 'ordereddict.pyc')] +orphaned_pyc_files = [ + os.path.join(SPACK_EXTERNAL_LIBS, 'functools.pyc'), + os.path.join(SPACK_EXTERNAL_LIBS, 'ordereddict.pyc'), + os.path.join(SPACK_LIB_PATH, 'spack', 'platforms', 'cray_xc.pyc'), + os.path.join(SPACK_LIB_PATH, 'spack', 'cmd', 'package-list.pyc'), + os.path.join(SPACK_LIB_PATH, 'spack', 'cmd', 'test-install.pyc'), + os.path.join(SPACK_LIB_PATH, 'spack', 'cmd', 'url-parse.pyc'), + os.path.join(SPACK_LIB_PATH, 'spack', 'test', 'yaml.pyc') +] + for pyc_file in orphaned_pyc_files: if not os.path.exists(pyc_file): continue try: os.remove(pyc_file) except OSError as e: - print "WARNING: Spack may fail mysteriously. Couldn't remove orphaned .pyc file: %s" % pyc_file + print ("WARNING: Spack may fail mysteriously. " + "Couldn't remove orphaned .pyc file: %s" % pyc_file) # If there is no working directory, use the spack prefix. try: @@ -77,7 +83,7 @@ import llnl.util.tty as tty from llnl.util.tty.color import * import spack from spack.error import SpackError -from external import argparse +import argparse # Command parsing parser = argparse.ArgumentParser( @@ -107,6 +113,8 @@ parser.add_argument('-p', '--profile', action='store_true', help="Profile execution using cProfile.") parser.add_argument('-v', '--verbose', action='store_true', help="Print additional output during builds") +parser.add_argument('-s', '--stacktrace', action='store_true', + help="Add stacktrace information to all printed statements") parser.add_argument('-V', '--version', action='version', version="%s" % spack.spack_version) @@ -114,30 +122,29 @@ parser.add_argument('-V', '--version', action='version', # subparser for setup. subparsers = parser.add_subparsers(metavar='SUBCOMMAND', dest="command") + import spack.cmd for cmd in spack.cmd.commands: module = spack.cmd.get_module(cmd) - subparser = subparsers.add_parser(cmd, help=module.description) + cmd_name = cmd.replace('_', '-') + subparser = subparsers.add_parser(cmd_name, help=module.description) 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() -def main(): +def _main(args, unknown_args): # Set up environment based on args. tty.set_verbose(args.verbose) tty.set_debug(args.debug) + tty.set_stacktrace(args.stacktrace) spack.debug = args.debug if spack.debug: import spack.util.debug as debug debug.register_interrupt_handler() + # Run any available pre-run hooks + spack.hooks.pre_run() + spack.spack_working_dir = working_dir if args.mock: from spack.repository import RepoPath @@ -145,13 +152,26 @@ def main(): # If the user asked for it, don't check ssl certs. if args.insecure: - tty.warn("You asked for --insecure, which does not check SSL certificates.") - spack.curl.add_default_arg('-k') + tty.warn("You asked for --insecure. Will NOT check SSL certificates.") + spack.insecure = True # Try to load the particular command asked for and run it - command = spack.cmd.get_command(args.command) + command = spack.cmd.get_command(args.command.replace('-', '_')) + + # Allow commands to inject an optional argument and get unknown args + # if they want to handle them. + info = dict(inspect.getmembers(command)) + varnames = info['__code__'].co_varnames + argcount = info['__code__'].co_argcount + + # Actually execute the command try: - return_val = command(parser, args) + if argcount == 3 and varnames[2] == 'unknown_args': + return_val = command(parser, args, unknown_args) + else: + if unknown_args: + tty.die('unrecognized arguments: %s' % ' '.join(unknown_args)) + return_val = command(parser, args) except SpackError as e: e.die() except KeyboardInterrupt: @@ -164,13 +184,29 @@ def main(): elif isinstance(return_val, int): sys.exit(return_val) else: - tty.die("Bad return value from command %s: %s" % (args.command, return_val)) - -if args.profile: - import cProfile - cProfile.run('main()', sort='tottime') -elif args.pdb: - import pdb - pdb.run('main()') -else: - main() + tty.die("Bad return value from command %s: %s" + % (args.command, return_val)) + + +def main(args): + # Just print help and exit if run with no arguments at all + if len(args) == 1: + parser.print_help() + sys.exit(1) + + # actually parse the args. + args, unknown = parser.parse_known_args() + + if args.profile: + import cProfile + cProfile.runctx('_main(args, unknown)', globals(), locals(), + sort='time') + elif args.pdb: + import pdb + pdb.runctx('_main(args, unknown)', globals(), locals()) + else: + _main(args, unknown) + + +if __name__ == '__main__': + main(sys.argv) |