Source code for crl.devutils.runner
from __future__ import print_function
import subprocess
__copyright__ = 'Copyright (C) 2019, Nokia'
[docs]class Failure(Exception):
pass
[docs]class Result(object):
def __init__(self, cmd, returncode, stdout='', stderr=''):
self.cmd = cmd
self.returncode = returncode
self.stdout = _bytes_to_unicode(stdout)
self.stderr = _bytes_to_unicode(stderr)
def __str__(self):
return ('cmd: {cmd}\n'
'stdout:\n{stdout}\n'
'stderr:\n{stderr}\n'
'returncode: {returncode}'.format(
cmd=self.cmd,
stdout=self.stdout,
stderr=self.stderr,
returncode=self.returncode))
[docs]def run(cmd, replaced_output=None, shell=True,
verbose=False, env=None, ignore_codes=None):
"""
Run shell command and return Result object.
Args:
cmd: Command to be executed.
replaced_output:
Replace stdout with replaced_output and return empty stderr.
shell:
If or not, the given command must be executed through the shell.
verbose: If or not, task execution must be displayed in more detail.
env: Environment defining any variables needed for the new process.
ignore_codes: A list of exit codes that the command must ignore.
Raises:
Failure: If the command exited with exit code greater than zero
and it is not in list of ignore codes.
"""
if ignore_codes is None:
ignore_codes = []
kwargs = {'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE,
'shell': shell}
if env:
kwargs['env'] = env
s = subprocess.Popen(cmd,
**kwargs)
out, err = s.communicate()
result = (Result(cmd=replaced_output, returncode=s.returncode)
if replaced_output else
Result(cmd, s.returncode, out, err))
if verbose:
print(result)
if result.returncode and result.returncode not in ignore_codes:
raise Failure(result)
return result
def _bytes_to_unicode(x):
try:
return x.decode('utf-8')
except AttributeError:
return x