]> arthur.barton.de Git - bup.git/commitdiff
exc: support input arg; return SubprocInfo from exc and exo
authorRob Browning <rlb@defaultvalue.org>
Sun, 26 Nov 2017 19:24:41 +0000 (13:24 -0600)
committerRob Browning <rlb@defaultvalue.org>
Sun, 24 Dec 2017 20:28:24 +0000 (14:28 -0600)
Change exo to return a namedtuple so that you can refer to bits of the
result by name.

Base exc on exo so that it can support an input arg (even in python2),
and change both exc and exo to be a thinner wrapper around Popen so
that the arguments will behave roughly the same.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
buptest.py
t/test-prune-older

index 135713e104c2f845961fd77eb6f19177f4f657d7..14ca1c388e58c1a3d7bc967fa1ec812109445d22 100644 (file)
@@ -1,5 +1,6 @@
 
 from __future__ import print_function
+from collections import namedtuple
 from contextlib import contextmanager
 from os.path import basename, dirname, realpath
 from pipes import quote
@@ -52,19 +53,35 @@ def logcmd(cmd):
     else:
         print(' '.join(map(quote, cmd)), file=sys.stderr)
 
-def exc(cmd, shell=False):
-    logcmd(cmd)
-    check_call(cmd, shell=shell)
 
-def exo(cmd, stdin=None, stdout=True, stderr=False, shell=False, check=True):
+SubprocInfo = namedtuple('SubprocInfo', ('out', 'err', 'rc', 'p'))
+
+def exo(cmd, input=None, stdin=None, stdout=PIPE, stderr=PIPE,
+        shell=False, check=True):
+    """Print cmd to stderr, run it, and return the resulting SubprocInfo.
+    The keyword arguments are passed to Popen, and the defaults
+    capture both stdout and stderr.
+
+    """
     logcmd(cmd)
     p = Popen(cmd,
-              stdin=None,
-              stdout=(PIPE if stdout else None),
-              stderr=PIPE,
+              stdin=(PIPE if input else stdin),
+              stdout=stdout,
+              stderr=stderr,
               shell=shell)
-    out, err = p.communicate()
+    out, err = p.communicate(input=input)
     if check and p.returncode != 0:
-        raise Exception('subprocess %r failed with status %d, stderr: %r'
-                        % (' '.join(map(quote, cmd)), p.returncode, err))
-    return out, err, p
+        raise Exception('subprocess %r failed with status %d%s'
+                        % (' '.join(map(quote, cmd)),
+                           p.returncode,
+                           (', stderr: %r' % err) if stderr else ''))
+    return SubprocInfo(out=out, err=err, rc=p.returncode, p=p)
+
+def exc(cmd, input=None, stdout=None, stderr=None, shell=False, check=True):
+    """Print cmd to stderr, run it, and return the resulting SubprocInfo.
+    The keyword arguments are passed to Popen, and the defaults
+    allow stdout and stderr to pass through.
+
+    """
+    return exo(cmd, input=input, stdout=stdout, stderr=stderr, shell=shell,
+               check=check)
index 9e9d359b7568b707b5c9de366da2c56d3a4ec8da..e0f5e332085fca784c84f8c031b57cecbae9b50d 100755 (executable)
@@ -13,6 +13,7 @@ from os import environ, chdir
 from os.path import abspath, dirname
 from random import choice, randint
 from shutil import copytree, rmtree
+from subprocess import PIPE
 from sys import stderr
 from time import localtime, strftime, time
 import os, random, sys
@@ -29,7 +30,7 @@ from bup.helpers import partition, period_as_secs, readpipe
 
 
 def bup(*args):
-    return exo((bup_cmd,) + args)[0]
+    return exo((bup_cmd,) + args).out
 
 def bupc(*args):
     return exc((bup_cmd,) + args)
@@ -127,7 +128,7 @@ def result_diffline(x):
 def check_prune_result(expected):
     actual = sorted([int(x)
                      for x in exo(['git', 'log',
-                                   '--pretty=format:%at'])[0].splitlines()])
+                                   '--pretty=format:%at']).out.splitlines()])
     if expected != actual:
         for x in expected:
             print('ex:', x, strftime('%Y-%m-%d-%H%M%S', localtime(x)),
@@ -164,19 +165,19 @@ with test_tempdir('prune-older-') as tmpdir:
     chdir(tmpdir + '/work')
     save_utcs = create_older_random_saves(save_population, three_years_ago, now)
     chdir(tmpdir)
-    test_set_hash = exo(['git', 'show-ref', '-s', 'master'])[0].rstrip()
+    test_set_hash = exo(['git', 'show-ref', '-s', 'master']).out.rstrip()
     ls_saves = bup('ls', 'master').splitlines()
     wvpasseq(save_population + 1, len(ls_saves))
 
     wvstart('ensure everything kept, if no keep arguments')
     exc(['git', 'reset', '--hard', test_set_hash])
-    _, errmsg, proc = exo((bup_cmd,
-                           'prune-older', '-v', '--unsafe', '--no-gc',
-                           '--wrt', str(now)) \
-                          + ('master',),
-                          stdout=False, stderr=True, check=False)
-    wvpassne(proc.returncode, 0)
-    wvpass('at least one keep argument is required' in errmsg)
+    proc = exo((bup_cmd,
+                'prune-older', '-v', '--unsafe', '--no-gc',
+                '--wrt', str(now)) \
+               + ('master',),
+               stdout=None, stderr=PIPE, check=False)
+    wvpassne(proc.rc, 0)
+    wvpass('at least one keep argument is required' in proc.err)
     check_prune_result(save_utcs)