diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/docs/basic_usage.rst | 69 | ||||
-rw-r--r-- | lib/spack/docs/getting_started.rst | 31 | ||||
-rw-r--r-- | lib/spack/docs/index.rst | 4 | ||||
-rw-r--r-- | lib/spack/spack/util/executable.py | 49 |
4 files changed, 99 insertions, 54 deletions
diff --git a/lib/spack/docs/basic_usage.rst b/lib/spack/docs/basic_usage.rst index ed79790bb9..0578f0c8db 100644 --- a/lib/spack/docs/basic_usage.rst +++ b/lib/spack/docs/basic_usage.rst @@ -3,18 +3,16 @@ Basic usage ===================== -Spack is implemented as a single command (``spack``) with many -*subcommands*. Only a small subset of commands is needed for typical -usage. +The ``spack`` command has many *subcommands*. You'll only need a +small subset of them for typical usage. Listing available packages ------------------------------ -The first thing you likely want to do with spack is to install some -software. Before that, you need to know what's available. You can -see available package names either using the :ref:`package-list`, or -using the commands below. +To install software with Spack, you need to know what software is +available. You can see a list of available package names at the +:ref:`package-list` webpage, or using the ``spack list`` command. .. _spack-list: @@ -43,54 +41,55 @@ To get more information on a particular package from `spack list`, use .. command-output:: spack info mpich -Most of the information is self-explanatory. *Safe versions* are -versions that Spack has a checksum for, and Spack will use the -checksum to ensure they downloaded without any errors or malicious -attacks. :ref:`Dependencies <sec-specs>` and :ref:`virtual -dependencies <sec-virtual-dependencies>`, are described in more detail -later. +Most of the information is self-explanatory. The *safe versions* are +versions that Spack knows the checksum for, and it will use the +checksum to verify that these versions download without errors or +viruses. + +:ref:`Dependencies <sec-specs>` and :ref:`virtual dependencies +<sec-virtual-dependencies>` are described in more detail later. .. _spack-versions: ``spack versions`` ~~~~~~~~~~~~~~~~~~~~~~~~ -To see *more* available versions of a package, run ``spack versions``, -for example: +To see *more* available versions of a package, run ``spack versions``. +For example: .. command-output:: spack versions libelf -There are two sections in the output. *Safe versions* are ones that -have already been checksummed. Spack goes a step further, though, and -also shows you what versions are available out on the web---these are -*remote versions*. Spack gets this information by scraping it -directly from web pages. Depending on the package, Spack may or may -not be able to find any remote versions. +There are two sections in the output. *Safe versions* are versions +for which Spack has a checksum on file. It can verify that these +versions are downloaded correctly. + +In many cases, Spack can also show you what versions are available out +on the web---these are *remote versions*. Spack gets this information +by scraping it directly from package web pages. Depending on the +package and how its releases are organized, Spack may or may not be +able to find remote versions. Installing and uninstalling ------------------------------ -Now that you know how to list available packages and versions, you're -ready to start installing things. - .. _spack-install: ``spack install`` ~~~~~~~~~~~~~~~~~~~~~ ``spack install`` will install any package shown by ``spack list``. -To install the latest version of a package, along with all of its -dependencies, simply give it a package name: +For example, To install the latest version of the ``mpileaks`` +package, you might type this: .. code-block:: sh $ spack install mpileaks -If `mpileaks` depends on other packages, Spack will install those -first. It then fetches the tarball for ``mpileaks``, expands it, -verifies that it was downloaded without errors, builds it, and -installs it in its own directory under ``$SPACK_HOME/opt``. You'll see +If `mpileaks` depends on other packages, Spack will install the +dependencies first. It then fetches the ``mpileaks`` tarball, expands +it, verifies that it was downloaded without errors, builds it, and +installs it in its own directory under ``$SPACK_ROOT/opt``. You'll see a number of messages from spack, a lot of build output, and a message that the packages is installed: @@ -139,11 +138,11 @@ an installation. Spack is unique in that it can also configure the configurations of the same version of a package, one built with boost 1.39.0, and the other version built with version 1.43.0, can coexist. -This can all be done on the command line using special syntax. Spack -calls the descriptor used to refer to a particular package -configuration a **spec**. In the command lines above, both -``mpileaks`` and ``mpileaks@3.0.4`` are specs. Specs are described in -detail in :ref:`sec-specs`. +This can all be done on the command line using the *spec* syntax. +Spack calls the descriptor used to refer to a particular package +configuration a **spec**. In the commands above, ``mpileaks`` and +``mpileaks@3.0.4``. We'll talk more about how you can use them to +customize an installation in :ref:`sec-specs`. .. _spack-uninstall: diff --git a/lib/spack/docs/getting_started.rst b/lib/spack/docs/getting_started.rst index a28883259f..d958d9e74a 100644 --- a/lib/spack/docs/getting_started.rst +++ b/lib/spack/docs/getting_started.rst @@ -12,20 +12,30 @@ Getting spack is easy. You can clone it from the `github repository $ git clone https://github.com/scalability-llnl/spack.git This will create a directory called ``spack``. We'll assume that the -full path to this directory is in some environment called -``SPACK_HOME``. Add ``$SPACK_HOME/bin`` to your path and you're ready -to go: +full path to this directory is in the ``SPACK_ROOT`` environment +variable. Add ``$SPACK_ROOT/bin`` to your path and you're ready to +go: .. code-block:: sh - $ export PATH=spack/bin:$PATH + $ export PATH=$SPACK_ROOT/bin:$PATH $ spack install libelf -In general, most of your interactions with Spack will be through the -``spack`` command. +For a richer experience, use Spack's `shell support +<http://scalability-llnl.github.io/spack/basic_usage.html#environment-modules>`_: +.. code-block:: sh + + # For bash users + $ . $SPACK_ROOT/share/spack/setup-env.sh + + # For tcsh or csh users (note you must set SPACK_ROOT) + $ setenv SPACK_ROOT /path/to/spack + $ source $SPACK_ROOT/share/spack/setup-env.csh + +This automatically adds Spack to your ``PATH``. -Install +Installation -------------------- You don't need to install Spack; it's ready to run as soon as you @@ -39,6 +49,7 @@ functionality. To install spack in a new directory, simply type: $ spack bootstrap /my/favorite/prefix -This will install a new spack script in /my/favorite/prefix/bin, which -you can use just like you would the regular spack script. Each copy -of spack installs packages into its own ``$PREFIX/opt`` directory. +This will install a new spack script in ``/my/favorite/prefix/bin``, +which you can use just like you would the regular spack script. Each +copy of spack installs packages into its own ``$PREFIX/opt`` +directory. diff --git a/lib/spack/docs/index.rst b/lib/spack/docs/index.rst index 2382678cc3..97c8361421 100644 --- a/lib/spack/docs/index.rst +++ b/lib/spack/docs/index.rst @@ -18,8 +18,8 @@ configurations can coexist on the same system. Most importantly, Spack is *simple*. It offers a simple *spec* syntax so that users can specify versions and configuration options concisely. Spack is also simple for package authors: package files -are writtin in pure Python, and specs allow package authors to write a -single build script for many different builds of the same package. +are writtin in pure Python, and specs allow package authors to +maintain a single file for many different builds of the same package. See the :doc:`features` for examples and highlights. diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py index 923c7c19a5..81759d3053 100644 --- a/lib/spack/spack/util/executable.py +++ b/lib/spack/spack/util/executable.py @@ -28,8 +28,10 @@ import os import sys import re import subprocess +import inspect import llnl.util.tty as tty +import spack import spack.error class Executable(object): @@ -38,6 +40,9 @@ class Executable(object): self.exe = name.split(' ') self.returncode = None + if not self.exe: + raise ProcessError("Cannot construct executable for '%s'" % name) + def add_default_arg(self, arg): self.exe.append(arg) @@ -63,7 +68,9 @@ class Executable(object): "Consider removing them") cmd = self.exe + list(args) - tty.debug(" ".join(cmd)) + + cmd_line = ' '.join(cmd) + tty.debug(cmd_line) close_error = False try: @@ -79,16 +86,22 @@ class Executable(object): self.returncode = proc.returncode if fail_on_error and proc.returncode != 0: - raise ProcessError("command '%s' returned error code %d" - % (" ".join(cmd), proc.returncode)) + raise ProcessError("Command exited with status %d:" + % proc.returncode, cmd_line) if return_output: return out + except OSError, e: + raise ProcessError( + "%s: %s" % (self.exe[0], e.strerror), + "Command: " + cmd_line) + except subprocess.CalledProcessError, e: if fail_on_error: raise ProcessError( - "command '%s' failed to run." % ( - " ".join(cmd), proc.returncode), str(e)) + str(e), + "\nExit status %d when invoking command: %s" + % (proc.returncode, cmd_line)) finally: if close_error: @@ -130,5 +143,27 @@ def which(name, **kwargs): class ProcessError(spack.error.SpackError): - def __init__(self, msg, *long_msg): - super(ProcessError, self).__init__(msg, *long_msg) + def __init__(self, msg, long_msg=None): + # Friendlier exception trace info for failed executables + long_msg = long_msg + "\n" if long_msg else "" + for f in inspect.stack(): + frame = f[0] + loc = frame.f_locals + if 'self' in loc: + obj = loc['self'] + if isinstance(obj, spack.Package): + long_msg += "---\n" + long_msg += "Context:\n" + long_msg += " %s:%d, in %s:\n" % ( + inspect.getfile(frame.f_code), + frame.f_lineno, + frame.f_code.co_name) + + lines, start = inspect.getsourcelines(frame) + for i, line in enumerate(lines): + mark = ">> " if start + i == frame.f_lineno else " " + long_msg += " %s%-5d%s\n" % ( + mark, start + i, line.rstrip()) + break + + super(ProcessError, self).__init__(msg, long_msg) |