summaryrefslogtreecommitdiff
path: root/bin/spack
blob: e9307d1485ac0284521b7d5513d727143ce0b009 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env python
##############################################################################
# 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, n)
                      for n in ('functools.pyc', 'ordereddict.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)
    subparser = subparsers.add_parser(cmd, 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, which does 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)
    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='tottime')
elif args.pdb:
    import pdb
    pdb.run('main()')
else:
    main()