#!/usr/bin/env python # flake8: noqa ############################################################################## # Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC. # Produced at the Lawrence Livermore National Laboratory. # # This file is part of Spack. # Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. # LLNL-CODE-647188 # # For details, see https://github.com/llnl/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 Lesser General Public License (as # published by the Free Software Foundation) version 2.1, 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 Lesser 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 if not 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) import os # Find spack's location and its prefix. SPACK_FILE = os.path.realpath(os.path.expanduser(__file__)) os.environ["SPACK_FILE"] = SPACK_FILE 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) 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, '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') ] 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) # If there is no working directory, use the spack prefix. try: working_dir = os.getcwd() except OSError: os.chdir(SPACK_PREFIX) working_dir = SPACK_PREFIX # clean up the scope and start using spack package instead. del SPACK_FILE, SPACK_PREFIX, SPACK_LIB_PATH import llnl.util.tty as tty from llnl.util.tty.color import * import spack from spack.error import SpackError import argparse # Command parsing parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter, description="Spack: the Supercomputing PACKage Manager." + colorize(""" spec expressions: PACKAGE [CONSTRAINTS] CONSTRAINTS: @c{@version} @g{%compiler @compiler_version} @B{+variant} @r{-variant} or @r{~variant} @m{=architecture} [^DEPENDENCY [CONSTRAINTS] ...]""")) parser.add_argument('-d', '--debug', action='store_true', help="Write out debug logs during compile") parser.add_argument('-D', '--pdb', action='store_true', help="Run spack under the pdb debugger") parser.add_argument('-k', '--insecure', action='store_true', help="Do not check ssl certificates when downloading.") parser.add_argument('-m', '--mock', action='store_true', help="Use mock packages instead of real ones.") 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('-V', '--version', action='version', version="%s" % spack.spack_version) # each command module implements a parser() function, to which we pass its # 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) 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(): # Set up environment based on args. tty.set_verbose(args.verbose) tty.set_debug(args.debug) spack.debug = args.debug if spack.debug: import spack.util.debug as debug debug.register_interrupt_handler() from spack.yaml_version_check import check_yaml_versions check_yaml_versions() spack.spack_working_dir = working_dir if args.mock: from spack.repository import RepoPath spack.repo.swap(RepoPath(spack.mock_packages_path)) # If the user asked for it, don't check ssl certs. if args.insecure: tty.warn("You asked for --insecure. Will NOT check SSL certificates.") spack.curl.add_default_arg('-k') # Try to load the particular command asked for and run it command = spack.cmd.get_command(args.command.replace('-', '_')) try: return_val = command(parser, args) except SpackError as e: e.die() except KeyboardInterrupt: sys.stderr.write('\n') tty.die("Keyboard interrupt.") # Allow commands to return values if they want to exit with some other code. if return_val is None: sys.exit(0) 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='time') elif args.pdb: import pdb pdb.run('main()') else: main()