diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py index 2b1b24b728..bc27b25889 100644 --- a/lib/spack/spack/util/executable.py +++ b/lib/spack/spack/util/executable.py @@ -22,7 +22,7 @@ # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -__all__ = ['Executable', 'when'] +__all__ = ['Executable', 'which', 'ProcessError'] import os import sys @@ -30,7 +30,7 @@ import subprocess import llnl.util.tty as tty -from spack.error import SpackError +import spack.error class Executable(object): """Class representing a program that can be run on the command line.""" @@ -52,6 +52,7 @@ def __call__(self, *args, **kwargs): """Run the executable with subprocess.check_output, return output.""" return_output = kwargs.get("return_output", False) fail_on_error = kwargs.get("fail_on_error", True) + error = kwargs.get("error", sys.stderr) quoted_args = [arg for arg in args if re.search(r'^"|^\'|"$|\'$', arg)] if quoted_args: @@ -64,22 +65,34 @@ def __call__(self, *args, **kwargs): cmd = self.exe + list(args) tty.debug(" ".join(cmd)) + close_error = False try: + if error is None: + error = open(os.devnull, 'w') + close_error = True + proc = subprocess.Popen( cmd, - stderr=sys.stderr, + stderr=error, stdout=subprocess.PIPE if return_output else sys.stdout) out, err = proc.communicate() self.returncode = proc.returncode if fail_on_error and proc.returncode != 0: - raise SpackError("command '%s' returned error code %d" - % (" ".join(cmd), proc.returncode)) + raise ProcessError("command '%s' returned error code %d" + % (" ".join(cmd), proc.returncode)) if return_output: return out except subprocess.CalledProcessError, e: - if fail_on_error: raise + if fail_on_error: + raise ProcessError( + "command '%s' failed to run." % ( + " ".join(cmd), proc.returncode), str(e)) + + finally: + if close_error: + error.close() def __eq__(self, other): @@ -114,3 +127,8 @@ def which(name, **kwargs): if required: tty.die("spack requires %s. Make sure it is in your path." % name) return None + + +class ProcessError(spack.error.SpackError): + def __init__(self, msg, *long_msg): + super(ProcessError, self).__init__(msg, *long_msg)