-from __future__ import print_function
+from __future__ import absolute_import, print_function
+from collections import namedtuple
from contextlib import contextmanager
-from os.path import basename, dirname, realpath
+from os.path import abspath, basename, dirname, realpath
from pipes import quote
-from subprocess import PIPE, Popen, check_call
+from subprocess import PIPE, Popen
from traceback import extract_stack
-import subprocess, sys, tempfile
+import errno, os, subprocess, sys, tempfile
from wvtest import WVPASSEQ, wvfailure_count
# Assumes (of course) this file is at the top-level of the source tree
_bup_tmp = realpath(dirname(__file__) + '/t/tmp')
-helpers.mkdirp(_bup_tmp)
+try:
+ os.makedirs(_bup_tmp)
+except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
@contextmanager
subprocess.call(['rm', '-rf', tmpdir])
+ex_res = namedtuple('SubprocResult', ['out', 'err', 'proc', 'rc'])
+
+def run(cmd, check=True, input=None, **kwargs):
+ """Run a subprocess as per subprocess.Popen(cmd, **kwargs) followed by
+ communicate(input=input). If check is true, then throw an
+ exception if the subprocess exits with non-zero status. Return a
+ SubprocResult tuple.
+
+ """
+ if input:
+ assert 'stdin' not in kwargs
+ kwargs['stdin'] = PIPE
+ p = Popen(cmd, **kwargs)
+ out, err = p.communicate(input=input)
+ if check and p.returncode != 0:
+ raise Exception('subprocess %r failed with status %d%s'
+ % (' '.join(map(quote, cmd)), p.returncode,
+ (', stderr: %r' % err) if err else ''))
+ return ex_res(out=out, err=err, proc=p, rc=p.returncode)
+
def logcmd(cmd):
if isinstance(cmd, basestring):
print(cmd, file=sys.stderr)
else:
print(' '.join(map(quote, cmd)), file=sys.stderr)
-def exc(cmd, shell=False):
+def ex(cmd, **kwargs):
+ """Print cmd to stderr and then run it as per ex(...).
+ Print the subprocess stderr to stderr if stderr=PIPE and there's
+ any data.
+ """
logcmd(cmd)
- check_call(cmd, shell=shell)
+ result = run(cmd, **kwargs)
+ if result.err:
+ sys.stderr.write(result.err)
+ return result
-def exo(cmd, stdin=None, stdout=True, stderr=False, shell=False, check=True):
- logcmd(cmd)
- p = Popen(cmd,
- stdin=None,
- stdout=(PIPE if stdout else None),
- stderr=PIPE,
- shell=shell)
- out, err = p.communicate()
- if check and p.returncode != 0:
- raise Exception('subprocess %r failed with status %d, stderr: %r'
- % (' '.join(map(quote, cmd)), p.returncode, err))
- return out, err, p
+def exo(cmd, **kwargs):
+ """Print cmd to stderr and then run it as per ex(..., stdout=PIPE).
+ Print the subprocess stderr to stderr if stderr=PIPE and there's
+ any data.
+
+ """
+ assert 'stdout' not in kwargs
+ kwargs['stdout'] = PIPE
+ return ex(cmd, **kwargs)