Executables can optionally ignore error output.
This commit is contained in:
parent
ae31838193
commit
f1bc65c132
1 changed files with 24 additions and 6 deletions
|
@ -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"
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue