Source code for pybsd.executors

# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals

import logging
import subprocess

from . import utils

__logger__ = logging.getLogger('pybsd')


[docs]class Executor(object): """Executes a command Adapted from https://github.com/ployground/ploy""" def __init__(self, instance=None, prefix_args=(), splitlines=False): self.instance = instance self.prefix_args = tuple(prefix_args) self.splitlines = splitlines def __call__(self, *cmd_args, **kwargs): args = self.prefix_args + cmd_args rc = kwargs.pop('rc', None) out = kwargs.pop('out', None) err = kwargs.pop('err', None) stdin = kwargs.pop('stdin', None) if self.instance is None: __logger__.debug('Executing locally:\n%s', args) popen_kwargs = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE) if stdin is not None: popen_kwargs['stdin'] = subprocess.PIPE proc = subprocess.Popen(args, **popen_kwargs) _out, _err = proc.communicate(input=stdin) _rc = proc.returncode else: pass # not supported yet _out = utils.safe_unicode(_out) _err = utils.safe_unicode(_err) out = utils.safe_unicode(out) err = utils.safe_unicode(err) result = [] if rc is None: result.append(_rc) else: try: if not any(x == _rc for x in rc): raise subprocess.CalledProcessError(_rc, ' '.join(args), _err) except TypeError: pass if rc != _rc: raise subprocess.CalledProcessError(_rc, ' '.join(args), _err) if out is None: if self.splitlines: _out = _out.splitlines() result.append(_out) else: if out != _out: if _rc == 0: __logger__.error(_out) raise subprocess.CalledProcessError(_rc, ' '.join(args), _err) if err is None: if self.splitlines: _err = _err.splitlines() result.append(_err) else: if err != _err: if _rc == 0: __logger__.error(_err) raise subprocess.CalledProcessError(_rc, ' '.join(args), _err) if len(result) == 0: return elif len(result) == 1: return result[0] return tuple(result)