[PATCH 2 of 5] ui: allow capture of subprocess output

Pierre-Yves David pierre-yves.david at ens-lyon.org
Thu Apr 23 18:56:22 CDT 2015


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1429797459 -3600
#      Thu Apr 23 14:57:39 2015 +0100
# Branch stable
# Node ID 8aea112e68b1f90f8b2917f06fd4081116502c64
# Parent  61a2951a30f7c18501027501f7642dd632e72fcd
ui: allow capture of subprocess output

We want to capture hooks output during bundle2 processing. For this purpose we
introduce a new 'subproc' argument to 'ui.pushbuffer'. When set, the output of
sub process created through 'ui.system' will be captured in the buffer too.

This will be used in the next changeset.

diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -443,11 +443,11 @@ class colorui(uimod.ui):
     def write_err(self, *args, **opts):
         if self._colormode is None:
             return super(colorui, self).write_err(*args, **opts)
 
         label = opts.get('label', '')
-        if self._bufferstates and self._bufferstates[-1]:
+        if self._bufferstates and self._bufferstates[-1][0]:
             return self.write(*args, **opts)
         if self._colormode == 'win32':
             for a in args:
                 win32print(a, super(colorui, self).write_err, **opts)
         else:
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -74,11 +74,12 @@ default = %s
 
 class ui(object):
     def __init__(self, src=None):
         # _buffers: used for temporary capture of output
         self._buffers = []
-        # _bufferstates: Should the temporary capture includes stderr
+        # _bufferstates:
+        #   Should the temporary capture includes stderr and subprocess output
         self._bufferstates = []
         self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
         self._reportuntrusted = True
         self._ocfg = config.config() # overlay
         self._tcfg = config.config() # trusted
@@ -538,16 +539,19 @@ class ui(object):
 
     @util.propertycache
     def paths(self):
         return paths(self)
 
-    def pushbuffer(self, error=False):
+    def pushbuffer(self, error=False, subproc=False):
         """install a buffer to capture standard output of the ui object
 
-        If error is True, the error output will be captured too."""
+        If error is True, the error output will be captured too.
+
+        If subproc is True, output from subprocess (typically hooks) will be
+        captured too."""
         self._buffers.append([])
-        self._bufferstates.append(error)
+        self._bufferstates.append((error, subproc))
 
     def popbuffer(self, labeled=False):
         '''pop the last buffer and return the buffered output
 
         If labeled is True, any labels associated with buffered
@@ -583,11 +587,11 @@ class ui(object):
             for a in args:
                 self.fout.write(str(a))
 
     def write_err(self, *args, **opts):
         try:
-            if self._bufferstates and self._bufferstates[-1]:
+            if self._bufferstates and self._bufferstates[-1][0]:
                 return self.write(*args, **opts)
             if not getattr(self.fout, 'closed', False):
                 self.fout.flush()
             for a in args:
                 self.ferr.write(str(a))
@@ -832,12 +836,15 @@ class ui(object):
 
     def system(self, cmd, environ={}, cwd=None, onerr=None, errprefix=None):
         '''execute shell command with appropriate output stream. command
         output will be redirected if fout is not stdout.
         '''
+        out = self.fout
+        if util.any(s[1] for s in self._bufferstates):
+            out = self
         return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
-                           errprefix=errprefix, out=self.fout)
+                           errprefix=errprefix, out=out)
 
     def traceback(self, exc=None, force=False):
         '''print exception traceback if traceback printing enabled or forced.
         only to call in exception handler. returns true if traceback
         printed.'''


More information about the Mercurial-devel mailing list