Commit fd39ff03 authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Enhancements to run function - can get stderr and/or return code

parent 577cf431
......@@ -34,6 +34,13 @@ execute them.
"""
class FSLNotPresent(Exception):
"""Error raised by the :func:`runfsl` function when ``$FSLDIR`` cannot
be found.
"""
pass
@contextlib.contextmanager
def dryrun(*args):
"""Context manager which causes all calls to :func:`run` to be logged but
......@@ -68,11 +75,29 @@ def _prepareArgs(args):
return list(args)
def run(*args):
def run(*args, **kwargs):
"""Call a command and return its output. You can pass the command and
arguments as a single string, or as a regular or unpacked sequence.
An exception is raised if the command returns a non-zero exit code, unless
the ``returnCode`` option is set to ``True``.
:arg err: Must be passed as a keyword argument. Defaults to
``False``. If ``True``, standard error is captured and
returned.
:arg ret: Must be passed as a keyword argument. Defaults to
``False``. If ``True``, and the command's return code
is non-0, an exception is not raised.
:returns: A string containing the command's standard output. Or,
if ``err is True`` and/or ``returnCode is True``, a tuple
containing the standard output, standard error (if
``err``), and return code (if ``returnCode``).
"""
err = kwargs.get('err', False)
ret = kwargs.get('ret', False)
args = _prepareArgs(args)
if DRY_RUN:
......@@ -81,13 +106,30 @@ def run(*args):
log.debug('run: {}'.format(' '.join(args)))
if DRY_RUN:
result = '<dryrun>'
stdout = '<dryrun>'
stderr = ''
else:
result = sp.check_output(args).decode('utf-8').strip()
proc = sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE)
stdout, stderr = proc.communicate()
retcode = proc.returncode
stdout = stdout.decode('utf-8').strip()
stderr = stderr.decode('utf-8').strip()
log.debug('stdout: {}'.format(stdout))
log.debug('stderr: {}'.format(stderr))
if not ret and (retcode != 0):
raise RuntimeError('{} returned non-zero exit code: {}'.format(
args[0], retcode))
results = [stdout]
log.debug('result: {}'.format(result))
if err: results.append(stderr)
if ret: results.append(retcode)
return result
if len(results) == 1: return results[0]
else: return tuple(results)
def runfsl(*args):
......@@ -96,7 +138,7 @@ def runfsl(*args):
"""
if fslplatform.fsldir is None:
raise RuntimeError('$FSLDIR is not set - FSL cannot be found!')
raise FSLNotPresent('$FSLDIR is not set - FSL cannot be found!')
args = _prepareArgs(args)
args[0] = op.join(fslplatform.fsldir, 'bin', args[0])
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment