diff options
-rw-r--r-- | ranger/ext/spawn.py | 41 | ||||
-rw-r--r-- | ranger/ext/vcs/vcs.py | 18 |
2 files changed, 43 insertions, 16 deletions
diff --git a/ranger/ext/spawn.py b/ranger/ext/spawn.py index b07dd2e0..393d48d9 100644 --- a/ranger/ext/spawn.py +++ b/ranger/ext/spawn.py @@ -5,15 +5,45 @@ from subprocess import Popen, PIPE, CalledProcessError ENCODING = 'utf-8' -def spawn(*args): - """Runs a program, waits for its termination and returns its stdout""" +def spawn(*args, **kwargs): + """Runs a program, waits for its termination and returns its stdout + + This function is similar to python 2.7's subprocess.check_output, + but is favored due to python 2.6 compatibility. + + The arguments may be: + + spawn(string) + spawn(command, arg1, arg2...) + spawn([command, arg1, arg2]) + + The string will be run through a shell, otherwise the command is executed + directly. + + The keyword argument "decode" determines if the output shall be decoded + with the encoding '%s'. + + Further keyword arguments are passed to Popen. + """ % (ENCODING, ) + if len(args) == 1: popen_arguments = args[0] shell = isinstance(popen_arguments, str) else: popen_arguments = args shell = False - process = Popen(popen_arguments, stdout=PIPE, shell=shell) + + if 'decode' in kwargs: + do_decode = kwargs['decode'] + del kwargs['decode'] + else: + do_decode = True + if 'stdout' not in kwargs: + kwargs['stdout'] = PIPE + if 'shell' not in kwargs: + kwargs['shell'] = shell + + process = Popen(popen_arguments, **kwargs) stdout, stderr = process.communicate() return_value = process.poll() if return_value: @@ -21,4 +51,7 @@ def spawn(*args): error.output = stdout raise error - return stdout.decode(ENCODING) + if do_decode: + return stdout.decode(ENCODING) + else: + return stdout diff --git a/ranger/ext/vcs/vcs.py b/ranger/ext/vcs/vcs.py index a101e3f4..cfdc1e3b 100644 --- a/ranger/ext/vcs/vcs.py +++ b/ranger/ext/vcs/vcs.py @@ -7,6 +7,7 @@ import os import subprocess import threading import time +from ranger.ext.spawn import spawn # Python2 compatibility try: @@ -119,20 +120,13 @@ class Vcs(object): # pylint: disable=too-many-instance-attributes with open(os.devnull, 'w') as devnull: try: if catchout: - process = subprocess.Popen(cmd, cwd=path, stdout=subprocess.PIPE, stderr=devnull) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - error = subprocess.CalledProcessError(retcode, cmd) - error.output = output - raise error - if retbytes: - return output - else: - output = output.decode('UTF-8') + output = spawn(cmd, cwd=path, stderr=devnull, + decode=not retbytes) + if (not retbytes and rstrip_newline and + output.endswith('\n')): if rstrip_newline and output.endswith('\n'): return output[:-1] - return output + return output else: subprocess.check_call(cmd, cwd=path, stdout=devnull, stderr=devnull) except (subprocess.CalledProcessError, FileNotFoundError): |