summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/ext/spawn.py41
-rw-r--r--ranger/ext/vcs/vcs.py18
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):